diff --git a/.gitignore b/.gitignore index 33c0294..d6d744a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,9 +29,13 @@ # Ignore the test DB db/test.sqlite3 +# Ignore the SimpleCov output +coverage + # Ignore database configuration and token secrets config/database.yml config/secrets.yml +config/branding.yml # Ignore some of the initializers config/initializers/recaptcha.rb @@ -57,3 +61,7 @@ # ignore yard generated documents /doc/* !/doc/README_FOR_APP + +# ignore auto-generated gettext files when running gettext:find +config/locale/*/app.edit.po +config/locale/*/app.po.time_stamp \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 6bbd6e5..453b68d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,13 @@ before_script: - cp config/database_example.yml config/database.yml - cp config/secrets_example.yml config/secrets.yml - - bundle exec rake db:migrate RAILS_ENV=test + - cp config/branding_example.yml config/branding.yml + - cp config/initializers/devise.rb.example config/initializers/devise.rb + - cp config/initializers/recaptcha.rb.example config/initializers/recaptcha.rb + - cp config/initializers/wicked_pdf.rb.example config/initializers/wicked_pdf.rb + - bundle exec rake db:drop RAILS_ENV=test + - bundle exec rake db:create RAILS_ENV=test + - bundle exec rake db:schema:load RAILS_ENV=test script: - bundle exec rake test diff --git a/Gemfile b/Gemfile index 6ccc952..2d9b5b9 100644 --- a/Gemfile +++ b/Gemfile @@ -15,8 +15,9 @@ # ------------------------------------------------ # DATABASE/SERVER -gem 'pg' gem 'mysql2', '~> 0.3.18' +gem 'pg' +gem 'flag_shih_tzu' # Allows for bitfields in activereccord # ------------------------------------------------ # JS <-> RUBY BRIDGE @@ -28,16 +29,12 @@ gem 'jbuilder' # ------------------------------------------------ -# CLONE ACTIVERECORD MODELS AND ASSOCIATIONS -gem 'amoeba' - -# ------------------------------------------------ # SLUGS/PERMALINKS gem 'friendly_id' # ------------------------------------------------ # SUPER ADMIN SECTION -gem 'activeadmin', github: 'activeadmin' +gem "administrate", :github => 'thoughtbot/administrate', :branch =>'v0.7.0' # ------------------------------------------------ # USERS @@ -46,6 +43,8 @@ gem 'devise_invitable' gem 'omniauth' gem 'omniauth-shibboleth' +gem 'omniauth-orcid' + #rolify for roles gem 'rolify' # Gems for repository integration @@ -60,11 +59,13 @@ gem 'sass-rails' gem 'less-rails' # WE SHOULD PROBABLY USE SASS OR LESS NOT BOTH gem 'jquery-rails' +gem 'font-awesome-rails' gem 'twitter-bootstrap-rails', '2.2.8' gem 'tinymce-rails' # WYSIWYG EDITOR -gem 'contact_us', '>= 1.2.0' # COULD BE EASILY REPLACED WITH OUR OWN CODE -gem 'recaptcha' +gem 'contact_us', '>= 1.2.0' # COULD BE EASILY REPLACED WITH OUR OWN CODE +gem 'recaptcha', '>= 4.0' gem 'dragonfly' # LOGO UPLOAD +gem 'formtastic' # ------------------------------------------------ # EXPORTING @@ -73,13 +74,14 @@ gem 'wicked_pdf' gem 'htmltoword' gem 'feedjira' -gem 'caracal' # WORD DOC EXPORTING -gem 'caracal-rails' gem 'yaml_db', :git => 'https://github.com/vyruss/yaml_db.git' # ------------------------------------------------ # INTERNATIONALIZATION gem "i18n-js", ">= 3.0.0.rc11" #damodar added TODO: explain +gem 'gettext_i18n_rails', '~> 1.8' +gem "gettext_i18n_rails_js", "~> 1.2.0" +gem 'gettext', '>=3.0.2', :require => false, :group => :development # ------------------------------------------------ # API @@ -102,13 +104,17 @@ gem 'minitest-rails-capybara' gem 'minitest-reporters' gem 'rack-test' + gem 'webmock' gem 'sqlite3' + gem 'simplecov', require: false end group :development do gem "better_errors" gem "binding_of_caller" gem 'web-console', '~>2.0' + gem 'rack-mini-profiler' + #gem 'flamegraph' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index d2532a9..53bf3cf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,21 +1,20 @@ GIT - remote: git://github.com/activeadmin/activeadmin.git - revision: f8926831429fe635d26ac8043ea5d676fb6ee637 + remote: git://github.com/thoughtbot/administrate.git + revision: 6bc227907e8567ca9d8c51658abc92fc2b19ca2d + branch: v0.7.0 specs: - activeadmin (1.0.0.pre4) - arbre (~> 1.0, >= 1.0.2) - bourbon - coffee-rails - formtastic (~> 3.1) - formtastic_i18n - inherited_resources (~> 1.6) - jquery-rails - jquery-ui-rails - kaminari (~> 0.15) - railties (>= 3.2, < 5.1) - ransack (~> 1.3) - sass-rails - sprockets (< 4.1) + administrate (0.7.0) + actionpack (>= 4.2, < 5.1) + actionview (>= 4.2, < 5.1) + activerecord (>= 4.2, < 5.1) + autoprefixer-rails (~> 6.0) + datetime_picker_rails (~> 0.0.7) + jquery-rails (>= 4.0) + kaminari (>= 1.0) + momentjs-rails (~> 2.8) + normalize-rails (>= 3.0) + sass-rails (~> 5.0) + selectize-rails (~> 0.6) GIT remote: https://github.com/vyruss/yaml_db.git @@ -64,12 +63,10 @@ thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) addressable (2.4.0) - amoeba (3.0.0) - activerecord (>= 3.2.6) ansi (1.5.0) - arbre (1.1.1) - activesupport (>= 3.0.0) arel (6.0.3) + autoprefixer-rails (6.7.7.2) + execjs bcrypt (3.1.11) better_errors (2.1.1) coderay (>= 1.0.0) @@ -77,9 +74,6 @@ rack (>= 0.9.0) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bourbon (4.2.7) - sass (~> 3.4) - thor (~> 0.19) builder (3.2.2) byebug (9.0.5) capybara (2.9.1) @@ -89,26 +83,16 @@ rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - caracal (1.0.8) - nokogiri (~> 1.6) - rubyzip (~> 1.1) - tilt (>= 1.4) - caracal-rails (1.0.1) - caracal (~> 1.0) - rails (>= 3.2) coderay (1.1.1) - coffee-rails (4.2.1) - coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.2.x) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.10.0) commonjs (0.2.7) concurrent-ruby (1.0.2) contact_us (1.2.0) rails (>= 4.2.0) + crack (0.4.3) + safe_yaml (~> 1.0.0) daemons (1.2.4) + datetime_picker_rails (0.0.7) + momentjs-rails (>= 2.8.1) debug_inspector (0.0.2) devise (4.2.0) bcrypt (~> 3.0) @@ -119,6 +103,7 @@ devise_invitable (1.7.0) actionmailer (>= 4.0.0) devise (>= 4.0.0) + docile (1.1.5) dragonfly (1.0.12) addressable (~> 2.3) multi_json (~> 1.0) @@ -130,21 +115,32 @@ multipart-post (>= 1.2, < 3) faraday_middleware (0.10.0) faraday (>= 0.7.4, < 0.10) + fast_gettext (1.3.0) feedjira (2.0.0) faraday (~> 0.9) faraday_middleware (~> 0.9) loofah (~> 2.0) sax-machine (~> 1.0) + flag_shih_tzu (0.3.15) + font-awesome-rails (4.7.0.1) + railties (>= 3.2, < 5.1) formtastic (3.1.4) actionpack (>= 3.2.13) - formtastic_i18n (0.6.0) friendly_id (5.1.0) activerecord (>= 4.0.0) + gettext (3.2.2) + locale (>= 2.0.5) + text (>= 1.3.0) + gettext_i18n_rails (1.8.0) + fast_gettext (>= 0.9.0) + gettext_i18n_rails_js (1.2.0) + gettext (>= 3.0.2) + gettext_i18n_rails (>= 0.7.1) + po_to_json (>= 1.0.0) + rails (>= 3.2.0) globalid (0.3.7) activesupport (>= 4.1.0) - has_scope (0.6.0) - actionpack (>= 3.2, < 5) - activesupport (>= 3.2, < 5) + hashdiff (0.3.0) hashie (3.4.6) htmltoword (0.5.1) actionpack @@ -153,11 +149,6 @@ i18n (0.7.0) i18n-js (3.0.0.rc14) i18n (~> 0.6, >= 0.6.6) - inherited_resources (1.6.0) - actionpack (>= 3.2, < 5) - has_scope (~> 0.6.0.rc) - railties (>= 3.2, < 5) - responders jbuilder (2.6.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) @@ -165,12 +156,20 @@ rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (5.0.5) - railties (>= 3.2.16) json (1.8.3) - kaminari (0.17.0) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) + jwt (1.5.6) + kaminari (1.0.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.0.1) + kaminari-activerecord (= 1.0.1) + kaminari-core (= 1.0.1) + kaminari-actionview (1.0.1) + actionview + kaminari-core (= 1.0.1) + kaminari-activerecord (1.0.1) + activerecord + kaminari-core (= 1.0.1) + kaminari-core (1.0.1) ledermann-rails-settings (2.4.2) activerecord (>= 3.1) less (2.6.0) @@ -181,6 +180,7 @@ sprockets (> 2, < 4) tilt libv8 (3.16.14.15) + locale (2.1.2) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.4) @@ -209,27 +209,44 @@ builder minitest (>= 5.0) ruby-progressbar + momentjs-rails (2.17.1) + railties (>= 3.1) multi_json (1.12.1) + multi_xml (0.5.5) multipart-post (2.0.0) mysql2 (0.3.21) nokogiri (1.6.8) mini_portile2 (~> 2.1.0) pkg-config (~> 1.1.7) + normalize-rails (4.1.1) + oauth2 (1.2.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) omniauth (1.3.1) hashie (>= 1.2, < 4) rack (>= 1.0, < 3) + omniauth-oauth2 (1.4.0) + oauth2 (~> 1.0) + omniauth (~> 1.2) + omniauth-orcid (1.2.1) + omniauth-oauth2 (~> 1.3) omniauth-shibboleth (1.2.1) omniauth (>= 1.0.0) orm_adapter (0.5.0) pg (0.19.0) pkg-config (1.1.7) - polyamorous (1.3.1) - activerecord (>= 3.0) + po_to_json (1.0.1) + json (>= 1.6.0) protected_attributes (1.1.3) activemodel (>= 4.0.1, < 5.0) pundit (1.1.0) activesupport (>= 3.0.0) rack (1.6.4) + rack-mini-profiler (0.10.1) + rack (>= 1.2.0) rack-test (0.6.3) rack (>= 1.0) rails (4.2.7) @@ -257,13 +274,7 @@ rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rake (11.3.0) - ransack (1.8.2) - actionpack (>= 3.0) - activerecord (>= 3.0) - activesupport (>= 3.0) - i18n - polyamorous (~> 1.3) - recaptcha (3.3.0) + recaptcha (4.1.0) json redcarpet (3.3.4) ref (2.0.0) @@ -272,6 +283,7 @@ rolify (5.1.0) ruby-progressbar (1.8.1) rubyzip (1.2.0) + safe_yaml (1.0.4) sass (3.4.22) sass-rails (5.0.6) railties (>= 4.0.0, < 6) @@ -280,6 +292,12 @@ sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) sax-machine (1.3.2) + selectize-rails (0.12.4) + simplecov (0.12.0) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) sprockets (3.7.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -291,6 +309,7 @@ swagger-docs (0.2.9) activesupport (>= 3) rails (>= 3) + text (1.3.1) therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref @@ -319,6 +338,10 @@ binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + webmock (2.1.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff wicked_pdf (1.1.0) wkhtmltopdf-binary (0.12.3) xpath (2.0.0) @@ -329,19 +352,22 @@ ruby DEPENDENCIES - activeadmin! - amoeba + administrate! better_errors binding_of_caller byebug - caracal - caracal-rails contact_us (>= 1.2.0) devise devise_invitable dragonfly feedjira + flag_shih_tzu + font-awesome-rails + formtastic friendly_id + gettext (>= 3.0.2) + gettext_i18n_rails (~> 1.8) + gettext_i18n_rails_js (~> 1.2.0) htmltoword i18n-js (>= 3.0.0.rc11) jbuilder @@ -353,18 +379,21 @@ minitest-reporters mysql2 (~> 0.3.18) omniauth + omniauth-orcid omniauth-shibboleth pg protected_attributes pundit + rack-mini-profiler rack-test rails (= 4.2.7) railties - recaptcha + recaptcha (>= 4.0) redcarpet responders (~> 2.0) rolify sass-rails + simplecov sqlite3 swagger-docs therubyracer (>= 0.11.4) @@ -373,6 +402,7 @@ twitter-bootstrap-rails (= 2.2.8) uglifier web-console (~> 2.0) + webmock wicked_pdf wkhtmltopdf-binary yaml_db! @@ -382,4 +412,4 @@ ruby 2.2.2p95 BUNDLED WITH - 1.13.2 + 1.14.6 diff --git a/README.md b/README.md index 5f2dfb9..0ae2435 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ * Rails >= 4.2 * MySql >= 5.0 OR PostgreSql -Further details on how to install Ruby on Rails applications are available from the Ruby on Rails site: http://rubyonrails.org +#### Migrating data from a running instance of DMPOnline_v4 or DMPTool +Migration instructions will be coming soon Further details on how to install MySQL and create your first user and database. Be sure to follow the instructions for your particular environment. * Install: http://dev.mysql.com/downloads/mysql/ diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb deleted file mode 100644 index 3aa2b89..0000000 --- a/app/admin/dashboard.rb +++ /dev/null @@ -1,39 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - - -ActiveAdmin.register_page "Dashboard" do - - menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") } - - content title: proc{ I18n.t("active_admin.dashboard") } do - #div class: "blank_slate_container", id: "dashboard_default_message" do - # span class: "blank_slate" do - # span I18n.t("active_admin.dashboard_welcome.welcome") - # small I18n.t("active_admin.dashboard_welcome.call_to_action") - # end - #end - - # Here is an example of a simple dashboard with columns and panels. - # - # columns do - # column do - # panel "Recent Posts" do - # ul do - # Post.recent(5).map do |post| - # li link_to(post.title, admin_post_path(post)) - # end - # end - # end - # end - - # column do - # panel "Info" do - # para "Welcome to ActiveAdmin." - # end - # end - # end - end # content -end \ No newline at end of file diff --git a/app/admin/dmptemplate.rb b/app/admin/dmptemplate.rb deleted file mode 100644 index e0cd394..0000000 --- a/app/admin/dmptemplate.rb +++ /dev/null @@ -1,125 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Dmptemplate do - permit_params :title, :description, :organisation_id, :published, :is_default - - menu :priority => 11, :label => proc{ I18n.t('admin.template')}, :parent => "Templates management" - - # FIXME: The below member_actions only work on :export settings. - member_action :settings do - @template = resource - @settings = resource.settings(:export) - end - - member_action :update_settings, method: :put do - new_settings = params[:settings][:export] - - settings = resource.settings(:export).tap do |s| - s.formatting, s.max_pages = if params[:commit] != 'Reset' - [ - new_settings[:formatting].try(:deep_symbolize_keys), - new_settings[:max_pages].try(:to_i) - ] - else - [ nil, nil ] - end - end - - if settings.save - redirect_to(action: :show, flash: { notice: I18n.t('admin.settings_updated') }) - else - settings.formatting = nil - @template = resource - @settings = settings - render(action: :settings) - end - end - - action_item(:edit) do - link_to(I18n.t('helpers.settings.title'), settings_admin_dmptemplate_path(resource.id)) - end - - index do - column :title do |dmptemp| - link_to dmptemp.title, [:admin, dmptemp] - end - column :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - column I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - if !org_title.organisation.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - else - '-' - end - end - column :published - column :is_default - - actions defaults: true do |template| - link_to(I18n.t('helpers.settings.title'), settings_admin_dmptemplate_path(template.id)) - end - end - - - # show Template details - show do - attributes_table do - row :title - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - if !org_title.organisation.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - else - '-' - end - end - row :published - row :is_default - row :created_at - row :updated_at - end - end - - #phases sidebar - sidebar I18n.t('admin.phases'), :only => :show, :if => proc { dmptemplate.phases.count >= 1} do - table_for dmptemplate.phases.order("number asc") do |temp_phases| - column :number - column :title do |row| - link_to row.title, [:admin, row] - end - end - end - - #form - form do |f| - f.inputs "Details" do - f.input :title - f.input :description - f.input :organisation_id, :label => I18n.t('admin.org_title'), - :as => :select, - :collection => Organisation.order('name').map{|orgp|[orgp.name, orgp.id]} - f.input :published - f.input :is_default - end - f.actions - end - - controller do - def permitted_params - params.permit! - end - end - -end - diff --git a/app/admin/guidance.rb b/app/admin/guidance.rb deleted file mode 100644 index f4400e9..0000000 --- a/app/admin/guidance.rb +++ /dev/null @@ -1,81 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Guidance do - permit_params :text, :guidance_group_id, :question_id - - menu :priority => 13, :label => proc{ I18n.t('admin.guidance')}, :parent => "Guidance list" - - index do - column (:text) { |guidance| raw(guidance.text) } - column I18n.t('admin.theme') do |t| - (t.themes.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - - column I18n.t('admin.question'), :sortable => :question_id do |que| - if !que.nil? then - que.question - else - '-' - end - end - - column I18n.t('admin.guidance_group') do |guidance| - (guidance.guidance_groups.map{|t_q| link_to t_q.name, [:admin, t_q]}).join(', ').html_safe - end - actions - end - - #show details of a question - show do - attributes_table do - row (:text) { |guidance| raw(guidance.text) } - - row I18n.t('admin.theme') do - (guidance.themes.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - row I18n.t('admin.question'), :question_id do |question| - question.question - end - row I18n.t('admin.guidance_group') do |guidance| - (guidance.guidance_groups.map{|t_q| link_to t_q.name, [:admin, t_q]}).join(', ').html_safe - end - - row :created_at - row :updated_at - end - end - - #form - form do |f| - f.inputs "Details" do - f.input :text - f.input :question_id, :as => :select, - :collection => Question.order('text').map{|que|[que.text, que.id]} - f.input :guidance_group_ids, :label => I18n.t('admin.guidance_group'), - :as => :select, - :collection => GuidanceGroup.order('name').map{|gui|[gui.name, gui.id]} - - end - f.inputs "Themes" do - f.input :theme_ids, :label => I18n.t('admin.selected_themes'), - :as => :select, - :include_blank => I18n.t('admin.all_themes'), - :multiple => true, - :collection => Theme.order('title').map{|the| [the.title, the.id]}, - :hint => I18n.t('admin.choose_themes') - end - - f.actions - end - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/admin/guidance_group.rb b/app/admin/guidance_group.rb deleted file mode 100644 index 76667f7..0000000 --- a/app/admin/guidance_group.rb +++ /dev/null @@ -1,80 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register GuidanceGroup do - permit_params :organisation_id, :name, :published, :optional_subset - - menu :priority => 2, :label => proc{I18n.t('admin.guidance_group')}, :parent => "Guidance list" - - index do - column I18n.t('admin.name'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - column I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - column I18n.t('admin.template') do |t| - (t.dmptemplates.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - - actions - end - - #show details of guidance group - show do - attributes_table do - row :name - row :organisation_id do |org_title| - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - row I18n.t('admin.template') do - (guidance_group.dmptemplates.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - row :created_at - row :updated_at - end - end - - #guidance list - sidebar I18n.t('admin.guidance'), :only => :show, :if => proc { guidance_group.guidances.count >= 1} do - table_for guidance_group.guidances.order("text asc") do |guis| - column :text do |gtext| - link_to gtext.text.html_safe, [:admin, gtext] - end - column I18n.t('admin.theme') do |themelist| - (themelist.themes.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - end - end - - #form - form do |f| - f.inputs "Details" do - f.input :name - f.input :organisation_id, :label => I18n.t('admin.org_title'), - :as => :select, - :collection => Organisation.order('name').map{|orgp|[orgp.name, orgp.id]} - f.input :published - f.input :optional_subset - end - - f.inputs "Templates" do - f.input :dmptemplate_ids, :label => I18n.t('admin.selected_templates'), - :as => :select, - :include_blank => I18n.t('admin.all_templates'), - :multiple => true, - :collection => Dmptemplate.order('title').map{|the| [the.title, the.id]}, - :hint => I18n.t('admin.choose_templates') - end - f.actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/language.rb b/app/admin/language.rb deleted file mode 100644 index 777478c..0000000 --- a/app/admin/language.rb +++ /dev/null @@ -1,45 +0,0 @@ -# [+Project:+] DMPonline -# [+Description:+] -# -# [+Created:+] 12/08/2016 -# [+Copyright:+] Digital Curation Centre - -ActiveAdmin.register Language do - permit_params :language_id, :name, :abbreviation, :default_language - - menu :priority => 10, :label => proc { I18n.t('admin.language') } - - index do - column I18n.t('admin.language_name'), :sortable => :name do |lang| - link_to lang.name, [:admin, lang] - end - column I18n.t('admin.language_abbreviation'), :sortable => :abbreviation do |lang| - link_to lang.abbreviation, [:admin, lang] - end - column I18n.t('admin.language_is_default'), :sortable => :default_language do |lang| - if lang[:default_language] - 'Yes' - else - 'No' - end - end - - actions - end - - show do - attributes_table do - row :name - row :abbreviation - row :default_language - row :description - end - end - - controller do - def permitted_params - params.permit! - end - end - -end \ No newline at end of file diff --git a/app/admin/option.rb b/app/admin/option.rb deleted file mode 100644 index ce44cfc..0000000 --- a/app/admin/option.rb +++ /dev/null @@ -1,79 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Option do - permit_params :question_id, :text, :number, :is_default - menu :priority => 6, :label => proc{I18n.t('admin.multi_options')}, :parent => "Templates management" - - index do - column :text - column I18n.t('admin.questions'), :sortable => :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.text, [:admin, ques.question] - end - end - column I18n.t('admin.sections'), :sortable => :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.section.title, [:admin, ques.question.section] - end - end - column I18n.t('admin.template'), :sortable => :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.section.version.phase.dmptemplate.title, [:admin, ques.question.section.version.phase.dmptemplate] - end - end - - actions - end - - #show details of a section - show do - attributes_table do - row :text - row :number - row I18n.t('admin.questions'), :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.text, [:admin, ques.question] - end - end - row I18n.t('admin.sections'), :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.section.title, [:admin, ques.question.section] - end - end - row I18n.t('admin.template'), :question_id do |ques| - if !ques.question_id.nil? then - link_to ques.question.section.version.phase.dmptemplate.title, [:admin, ques.question.section.version.phase.dmptemplate] - end - end - row :is_default - row :created_at - row :updated_at - end - end - - - #form - form do |f| - f.inputs "Details" do - f.input :text - f.input :number - f.input :question, - :as => :select, - :collection => Question.order('text').map{ |sec| ["#{truncate(sec.section.version.phase.dmptemplate.title, :lengh => 20)} - #{truncate(sec.section.title, :lengh => 50)} - #{truncate(sec.text, :lengh => 20)}", sec.id] } - f.input :is_default - end - - f.actions - end - - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/org_token_permission.rb b/app/admin/org_token_permission.rb deleted file mode 100644 index 4075d5cf..0000000 --- a/app/admin/org_token_permission.rb +++ /dev/null @@ -1,31 +0,0 @@ -ActiveAdmin.register OrgTokenPermission do - permit_params :organisation_id, :token_permission_type_id - - menu priority: 40, label: proc{ I18n.t('admin.org_token_permission')}, parent: "Api" - - index do - column I18n.t('admin.org') do |n| - link_to n.organisation, [:admin,n] - end - column I18n.t('admin.token_permission') do |n| - link_to n.token_permission_type, [:admin,n] - end - - actions - end - - show do - attributes_table do - row :organisation_id - row :token_permission_type_id - end - end - - controller do - def permitted_params - params.permit! - end - end - - -end diff --git a/app/admin/organisation.rb b/app/admin/organisation.rb deleted file mode 100644 index 5acc929..0000000 --- a/app/admin/organisation.rb +++ /dev/null @@ -1,112 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Organisation do - permit_params :abbreviation, :banner_file_id, :description, :domain, :logo_file_id, :name, :stylesheet_file_id, :target_url, :organisation_type_id, :wayfless_entity, :parent_id - - menu :priority => 14, :label => proc{I18n.t('admin.org')}, :parent => "Organisations management" - - index do - column I18n.t('admin.org_title'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - column I18n.t('admin.abbrev'), :sortable => :abbreviation do |ggn| - if !ggn.abbreviation.nil? - link_to ggn.abbreviation, [:admin, ggn] - else - '-' - end - end - column I18n.t('admin.org_type'), :sortable => :organisation_type_id do |org_type| - if !org_type.organisation_type_id.nil? then - link_to org_type.organisation_type.name, [:admin, org_type] - end - end - - actions - end - - - #show details of an organisation - show do - resource.check_api_credentials - attributes_table do - row I18n.t('admin.org_title'), :sortable => :name do |gn| - if !gn.name.nil? then - link_to gn.name, [:admin, gn] - end - end - row I18n.t('admin.abbrev'), :abbreviation do |ggn| - if !ggn.abbreviation.nil? - link_to ggn.abbreviation, [:admin, ggn] - else - '-' - end - end - row :sort_name - row I18n.t('admin.org_type'), :organisation_type_id do |org_type| - if !org_type.organisation_type_id.nil? then - link_to org_type.organisation_type.name, [:admin, org_type] - end - end - row :banner_text do |banner| - if !banner.banner_text.nil? then - banner.banner_text.html_safe - end - end - # row :target_url - row :logo_file_name - row :domain - row :wayfless_entity - row I18n.t('admin.token_permission_type') do - (organisation.token_permission_types.map{|tpt| link_to tpt.token_type, [:admin, tpt]}).join(', ').html_safe - end - row :created_at - row :updated_at - end - end - - #templates sidebar - sidebar I18n.t('admin.templates'), :only => :show, :if => proc { organisation.dmptemplates.count >= 1} do - table_for organisation.dmptemplates.order("title asc") do |temp| - column :title do |dmptemp| - link_to dmptemp.title, [:admin, dmptemp] - end - column :published - end - end - - #form - form do |f| - f.inputs "Details" do - f.input :name - f.input :abbreviation - f.input :sort_name - f.input :organisation_type_id, :label => I18n.t('admin.org_type'), :as => :select, :collection => OrganisationType.order('name').map{|orgt|[orgt.name, orgt.id]} - # f.input :target_url - f.input :banner_text - f.input :logo_file_name - f.input :domain - f.input :wayfless_entity - f.input :token_permission_types, label: I18n.t('admin.token_permission_type'), - as: :select, multiple: true, include_blank: I18n.t('helpers.none'), - collection: TokenPermissionType.order(:token_type).map{|token| [token.token_type, token.id]}, - hint: I18n.t('admin.choose_api_permissions') - # f.input :parent_id, :label => I18n.t('admin.org_parent'), :as => :select, :collection => Organisation.find(:all, :order => 'name ASC').map{|orgp|[orgp.name, orgp.id]} - # f.input :stylesheet_file_id - end - f.actions - end - - - controller do - def permitted_params - params.permit! - end - end - - -end diff --git a/app/admin/organisation_type.rb b/app/admin/organisation_type.rb deleted file mode 100644 index 4575f54..0000000 --- a/app/admin/organisation_type.rb +++ /dev/null @@ -1,55 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register OrganisationType do - permit_params :organisation_id, :name - - menu :priority => 4, :label => proc{I18n.t('admin.org_type')}, :parent => "Organisations management" - - index do - column I18n.t('admin.title'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - column I18n.t('admin.desc'), :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - - actions - end - - - #show organisation type details - show do - attributes_table do - row :name - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row :created_at - row :updated_at - end - end - - #organisations sidebar - sidebar I18n.t('admin.orgs'), :only => :show, :if => proc { organisation_type.organisations.count >= 1} do - table_for organisation_type.organisations.order("name") do |org_list| - column I18n.t('admin.org_title'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - end - end - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/admin/phase.rb b/app/admin/phase.rb deleted file mode 100644 index d7d061e..0000000 --- a/app/admin/phase.rb +++ /dev/null @@ -1,83 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Phase do - permit_params :description, :number, :title, :dmptemplate_id - - menu :priority => 10, :label => proc{I18n.t('admin.phase')}, :parent => "Templates management" - - index do - column :title, :sortable => :title do |ph| - if !ph.title.nil? then - link_to ph.title, [:admin, ph] - end - end - column :number - column I18n.t('admin.template'), :sortable => :dmptemplate_id do |temp_title| - if !temp_title.nil? then - if !temp_title.dmptemplate.nil? then - link_to temp_title.dmptemplate.title, [:admin, temp_title.dmptemplate] - else - "-" - end - end - end - - actions - end - - #show details of a phase - show do - attributes_table do - row :title - row :number - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row I18n.t('admin.template'), :sortable => :dmptemplate_id do |temp_title| - link_to temp_title.dmptemplate.title, [:admin, temp_title.dmptemplate] - end - row :created_at - row :updated_at - end - - end - - #versions sidebar - sidebar I18n.t('admin.version'), :only => :show, :if => proc { phase.versions.count >= 1} do - table_for phase.versions.order("number asc") do |temp_phases| - column :number - column :title do |row| - link_to row.title, [:admin, row] - end - column :published - end - end - - - #form - form do |f| - f.inputs "Details" do - f.input :title - f.input :number - f.input :description - f.input :dmptemplate_id, :label => I18n.t('admin.template'), - :as => :select, - :collection => Dmptemplate.order('title').map{|temp|[temp.title, temp.id]} - - end - f.actions - end - - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/project.rb b/app/admin/project.rb deleted file mode 100644 index 2028428..0000000 --- a/app/admin/project.rb +++ /dev/null @@ -1,39 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Project do - permit_params :dmptemplate_id, :title, :organisation_id, :unit_id, :guidance_group_ids, :project_group_ids, :funder_id, :institution_id, :grant_number,:identifier, :description, :principal_investigator, :principal_investigator_identifier, :data_contact - - menu :priority => 25, :label => proc{I18n.t('admin.plans')} - - - index do - column :title - column I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - if !org_title.organisation.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - else - '-' - end - end - column I18n.t('admin.template_title'), :sortable => :dmptemplate_id do |dmptemp| - if !dmptemp.dmptemplate.nil? then - link_to dmptemp.dmptemplate.title, [:admin, dmptemp.dmptemplate] - else - '-' - end - end - - actions - end - - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/project_group.rb b/app/admin/project_group.rb deleted file mode 100644 index 67c681c..0000000 --- a/app/admin/project_group.rb +++ /dev/null @@ -1,9 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register ProjectGroup do - menu false -end diff --git a/app/admin/question.rb b/app/admin/question.rb deleted file mode 100644 index 8d46df1..0000000 --- a/app/admin/question.rb +++ /dev/null @@ -1,131 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Question do - permit_params :default_value, :dependency_id, :dependency_text, :guidance, :number, :parent_id, :suggested_answer, :text, :question_type, :section_id - - menu :priority => 7, :label => proc{I18n.t('admin.question')}, :parent => "Templates management" - - index do - column I18n.t('admin.question'), :sortable => :text do |descr| - if !descr.text.nil? then - descr.text.html_safe - end - end - column I18n.t('admin.section_title'), :sortable => :section_id do |dmptemplate| - if !dmptemplate.section_id.nil? then - link_to dmptemplate.section.title, [:admin, dmptemplate.section] - end - end - column :number, :sortable => :number do |question_n| - if !question_n.number.nil? then - question_n.number - end - end - column I18n.t('admin.template_title'), :sortable => true do |dmptemplate| - if !dmptemplate.section_id.nil? then - if !dmptemplate.section.version.phase.dmptemplate.nil? then - link_to dmptemplate.section.version.phase.dmptemplate.title, [:admin, dmptemplate.section.version.phase.dmptemplate] - else - "-" - end - end - end - actions - end - - - #show details of a question - show do - attributes_table do - row :text do |descr| - if !descr.text.nil? then - descr.text.html_safe - end - end - row :section_id do |question| - link_to question.section.title, [:admin, question.section] - end - row :number - row :default_value - row I18n.t('admin.question_format') do |format| - link_to format.question_format.title, [:admin, format.question_format] - end - #row :guidance do |qguidance| - # if !qguidance.guidance.nil? then - # qguidance.guidance.html_safe - # end - #end - #row :parent_id do |qparent| - # if !qparent.parent_id.nil? then - # parent_q = Question.where('id = ?', qparent.parent_id) - # link_to parent_q.text, [:admin, parent_q] - # end - #end - #row :dependency_id do |qdepend| - # if !qdepend.dependency_id.nil? then - # qdep = Question.where('id = ?', qparent.dependency_id) - # link_to qdep.text, [:admin, qdep] - # end - #end - #row :dependency_text do |dep_text| - # if !dep_text.dependency_text.nil? then - # dep_text.dependency_text.html_safe - # end - #end - row I18n.t('admin.themes') do - (question.themes.map{|t_q| link_to t_q.title, [:admin, t_q]}).join(', ').html_safe - end - row :created_at - row :updated_at - - end - end - - - #form - form do |f| - f.inputs "Details" do - f.input :text - f.input :number - f.input :section, - :as => :select, - :collection => Section.order('title').map{ |sec| ["#{sec.version.phase.dmptemplate.title} - #{sec.title}", sec.id] } - f.input :default_value - # f.input :guidance - # f.input :parent_id, :label => "Parent", - # :as => :select, - # :collection => Question.find(:all, :order => 'text ASC').map{|que|[que.text, que.id]} - #f.input :dependency_id, :label => "Dependency question", - # :as => :select, - # :collection => Question.find(:all, :order => 'text ASC').map{|que|[que.text, que.id]} - # f.input :dependency_text - - end - f.inputs "Question Format" do - f.input :question_format_id, :label => I18n.t('admin.select_question_format'), - :as => :select, - :collection => QuestionFormat.order('title').map{|format| [format.title, format.id]} - end - f.inputs "Themes" do - f.input :theme_ids, :label => I18n.t('admin.selected_themes'), - :as => :select, - :multiple => true, - :include_blank => I18n.t('helpers.none'), - :collection => Theme.order('title').map{|the| [the.title, the.id]} , - :hint => I18n.t('admin.choose_themes') - - end - f.actions - end - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/admin/question_format.rb b/app/admin/question_format.rb deleted file mode 100644 index a5b9523..0000000 --- a/app/admin/question_format.rb +++ /dev/null @@ -1,39 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register QuestionFormat do - permit_params :description, :title - - menu :priority => 5, :label => proc{I18n.t('admin.question_format')}, :parent => "Templates management" - - index do - column I18n.t('admin.question_format'), :sortable => :title do |n| - link_to n.title, [:admin, n] - end - - actions - end - - # show Template details - show do - attributes_table do - row :title - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row :created_at - row :updated_at - end - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/role.rb b/app/admin/role.rb deleted file mode 100644 index dc386de..0000000 --- a/app/admin/role.rb +++ /dev/null @@ -1,62 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Role do - permit_params :name, :role_in_plans - - menu :priority => 5, :label => proc{I18n.t('admin.role')}, :parent => "User management" - - index do - column I18n.t('admin.title'), :sortable => :name do |role_name| - link_to role_name.name, [:admin, role_name] - end - - actions - end - - - show do - attributes_table do - row :name - row :role_in_plans - row :created_at - row :updated_at - end - - table_for( (Role.find(params[:id]).users)) do - column (:email){|user| link_to user.email, [:admin, user]} - column (:firstname){|user| user.firstname} - column (:surname){|user| user.surname} - column (:last_sign_in_at){|user| user.last_sign_in_at} - column (I18n.t('admin.org_title')){|user| - if !user.organisation.nil? then - if user.other_organisation.nil? || user.other_organisation == "" then - link_to user.organisation.name, [:admin, user.organisation] - else - I18n.t('helpers.org_type.org_name') + ' - ' + user.other_organisation - - end - end - } - end - - end - - form do |f| - f.inputs "Details" do - f.input :name - f.input :role_in_plans - end - - f.actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/section.rb b/app/admin/section.rb deleted file mode 100644 index c8ceab8..0000000 --- a/app/admin/section.rb +++ /dev/null @@ -1,93 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Section do - permit_params :organisation_id, :description, :number, :title, :version_id - - menu :priority => 8, :label => proc{I18n.t('admin.section')}, :parent => "Templates management" - - filter :title - filter :organisation - filter :version - filter :created_at - filter :updated_at - - - index do - column :title , :sortable => :title do |section| - if !section.title.nil? then - link_to section.title, [:admin, section] - end - end - column I18n.t('admin.version'), :sortable => :version_id do |version_title| - if !version_title.version_id.nil? then - link_to version_title.version.title, [:admin, version_title.version] - end - end - column I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - if !org_title.organisation_id.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - end - - actions - end - - #show details of a section - show do - attributes_table do - row :title - row :number - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row I18n.t('admin.version'), :sortable => :version_id do |version_title| - if !version_title.version_id.nil? then - link_to version_title.version.title, [:admin, version_title.version] - end - end - row I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - if !org_title.organisation_id.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - end - row :created_at - row :updated_at - end - - end - - - #questions sidebar(:default_value, :dependency_id, :dependency_text, :guidance, :number, :parent_id, :suggested_answer, :text, :question_type, :section_id) - sidebar proc{I18n.t("admin.questions")}, :only => :show, :if => proc { (Question.where("section_id = ?", params[:id])).count >= 1} do - table_for( Question.where("section_id = ?", params[:id] ).order("number")) do - column (:number){|question| question.number} - column (I18n.t("admin.question")){|question| link_to question.text, [:admin, question]} - end - - end - - #form - form do |f| - f.inputs "Details" do - f.input :title - f.input :number - f.input :version, :collection => Version.all.map{ |ver| [ver.title, ver.id] } - f.input :organisation, :as => :select, :collection => Organisation.order('name').map{|orgp|[orgp.name, orgp.id]} - f.input :description - end - - f.actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/suggested_answer.rb b/app/admin/suggested_answer.rb deleted file mode 100644 index ab957eb..0000000 --- a/app/admin/suggested_answer.rb +++ /dev/null @@ -1,33 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register SuggestedAnswer do - permit_params :question_id, :organisation_id - - menu :priority => 4, :label => proc{I18n.t('admin.sug_answer')}, :parent => "Templates management" - - - #form - form do |f| - f.inputs "Details" do - f.input :question_id, :label => I18n.t('admin.question'), - :as => :select, - :collection => Question.order('text').map{|ques|[ques.text, ques.id]} - f.input :organisation_id, :label => I18n.t('admin.org_title'), - :as => :select, - :collection => Organisation.order('name').map{|orgp|[orgp.name, orgp.id]} - f.input :text - f.input :is_example - end - f.actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/theme.rb b/app/admin/theme.rb deleted file mode 100644 index 913f32e..0000000 --- a/app/admin/theme.rb +++ /dev/null @@ -1,77 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Theme do - permit_params :description, :title, :locale - - menu :priority => 12, :label => "Themes" - - index do - column :title , :sortable => :title do |theme| - link_to theme.title, [:admin, theme] - end - column :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - - actions - end - - #show details of a theme - show do - attributes_table do - row :title - row :description - row :created_at - row :updated_at - end - - table_for( (Theme.find(params[:id]).questions).order('number')) do - column (:number){|question| question.number} - column (I18n.t("admin.question")){|question| link_to question.text, [:admin, question]} - column (I18n.t("admin.template")){|question| - if !question.section.nil? then - if !question.section.version.nil? then - if !question.section.version.phase.nil? then - if !question.section.version.phase.dmptemplate.nil? then - link_to question.section.version.phase.dmptemplate.title, [:admin, question.section.version.phase.dmptemplate] - else - I18n.t('admin.no_template') - end - else - I18n.t('admin.no_phase') - end - else - I18n.t('admin.no_version') - end - else - I18n.t('admin.no_section') - end - } - end - end - - - - #form - form do |f| - f.inputs "Details" do - f.input :title - f.input :description - end - f.actions - end - - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/admin/token_permission_type.rb b/app/admin/token_permission_type.rb deleted file mode 100644 index 5c804e8..0000000 --- a/app/admin/token_permission_type.rb +++ /dev/null @@ -1,33 +0,0 @@ -ActiveAdmin.register TokenPermissionType do - permit_params :token_type, :text_description - - menu priority: 40, label: proc{ I18n.t('admin.token_permission_type')}, parent: "Api" - - # TODO: Find better fix for the undefined method xxx_id_eq - remove_filter :org_token_permissions - - index do - column I18n.t('admin.token_permission_type'), sortable: :token_type do |n| - link_to n.token_type, [:admin, n] - end - column I18n.t('admin.permission_description') do |n| - link_to n.text_description, [:admin, n] - end - - actions - end - - show do - attributes_table do - row :token_type - row :text_description - end - end - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/admin/user.rb b/app/admin/user.rb deleted file mode 100644 index 464798b..0000000 --- a/app/admin/user.rb +++ /dev/null @@ -1,117 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register User do - permit_params :api_token, :password_confirmation, :encrypted_password, :remember_me, :id, :email, :firstname, :orcid_id, :shibboleth_id, :user_status_id, :surname, :user_type_id, :organisation_id, :skip_invitation, :other_organisation, :accept_terms, :role_ids - - menu :priority => 15, :label => proc{ I18n.t('admin.user')}, :parent => "User management" - - filter :firstname - filter :surname - filter :email - filter :organisation - filter :created_at - filter :updated_at - - - - index do - - column I18n.t('admin.user_name'), :sortable => :email do |user_email| - link_to user_email.email, [:admin, user_email] - end - column I18n.t('admin.firstname'), :sortable => :firstname do |use_first| - link_to use_first.firstname, [:admin, use_first] - end - column I18n.t('admin.surname'), :sortable => :surname do |user| - link_to user.surname, [:admin, user] - end - column I18n.t('admin.last_logged_in'), :last_sign_in_at - - column I18n.t('admin.org_title'), :sortable => 'organisation.name' do |org_title| - if !org_title.organisation.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - end - - actions - end - - show do - attributes_table do - row :firstname - row :surname - row :email - row :orcid_id - row I18n.t('admin.org_title'), :organisation_id do |org_title| - if !org_title.organisation_id.nil? then - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - end - row :other_organisation - # row I18n.t('admin.user_status'), :user_status_id do |us| - # if !us.user_status.nil? then - # link_to us.user_status.name, [:admin, us.user_status] - # end - # end - # row I18n.t('admin.user_type'), :user_type_id do |ut| - # if !ut.user_type.nil? then - # link_to ut.user_type.name, [:admin, ut.user_type] - # else - # '-' - # end - # end - row I18n.t('admin.user_role') do - (user.roles.map{|ro| link_to ro.name, [:admin, ro]}).join(', ').html_safe - end - # row :shibboleth_id - row :last_sign_in_at - row :sign_in_count - row :api_token - - end - end - - - form do |f| - f.inputs "Details" do - f.input :firstname - f.input :surname - f.input :email - f.input :orcid_id - f.input :api_token - # f.input :shibboleth_id - f.input :organisation_id, :label => I18n.t('admin.org_title'), - :as => :select, - :collection => Organisation.order('name').map{|orgp|[orgp.name, orgp.id]} - f.input :other_organisation - # f.input :user_status_id, :label => I18n.t('admin.user_status'), - # :as => :select, - # :collection => UserStatus.find(:all, :order => 'name ASC').map{|us|[us.name, us.id]} - # f.input :user_type_id, :label => I18n.t('admin.user_type'), - # :as => :select, - # :collection => UserType.find(:all, :order => 'name ASC').map{|ut|[ut.name, ut.id]} - f.input :role_ids, :label => I18n.t('admin.user_role'), - :as => :select, - :multiple => true, - :include_blank => I18n.t('helpers.none'), - :collection => Role.order('name').map{|ro| [ro.name, ro.id]} - end - - f.actions - end - - - - controller do - - def permitted_params - params.permit! - end - - end - -end diff --git a/app/admin/user_role_type.rb b/app/admin/user_role_type.rb deleted file mode 100644 index e40f5ee..0000000 --- a/app/admin/user_role_type.rb +++ /dev/null @@ -1,30 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register UserRoleType do - permit_params :description, :name - menu false - #:priority => 5, :label => proc{I18n.t('admin.user_role_type')}, :parent => "User management" - - index do - column I18n.t('admin.title'), :sortable => :name do |user_n| - link_to user_n.name, [:admin, user_n] - end - column I18n.t('admin.desc'),:description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - - actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/user_status.rb b/app/admin/user_status.rb deleted file mode 100644 index 856577c..0000000 --- a/app/admin/user_status.rb +++ /dev/null @@ -1,31 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register UserStatus do - permit_params :description, :name - - menu false - #:priority => 5, :label => proc{I18n.t('admin.user_status')}, :parent => "User management" - - index do - column I18n.t('admin.title'), :sortable => :name do |user_n| - link_to user_n.name, [:admin, user_n] - end - column I18n.t('admin.desc'),:description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - - actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/admin/user_type.rb b/app/admin/user_type.rb deleted file mode 100644 index 7836401..0000000 --- a/app/admin/user_type.rb +++ /dev/null @@ -1,42 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register UserType do - permit_params :description, :name - - menu false - #:priority => 5, :label => proc{I18n.t('admin.user_type')}, :parent => "User management" - - index do - column I18n.t('admin.user_type'), :sortable => :name do |user_n| - link_to user_n.name, [:admin, user_n] - end - - actions - end - - # show Template details - show do - attributes_table do - row :name - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row :created_at - row :updated_at - end - end - - controller do - def permitted_params - params.permit! - end - end - - -end diff --git a/app/admin/version.rb b/app/admin/version.rb deleted file mode 100644 index 7dbed51..0000000 --- a/app/admin/version.rb +++ /dev/null @@ -1,86 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register Version do - permit_params :description, :number, :published, :title, :phase_id - - menu :priority => 9, :label => proc{I18n.t('admin.version')}, :parent => "Templates management" - - index do - column I18n.t('admin.title'), :sortable => :title do |version_used| - if !version_used.title.nil? then - link_to version_used.title, [:admin, version_used] - end - end - column I18n.t('admin.version_numb'), :number - column :published - column I18n.t('admin.phase'), :sortable => :phase_id do |phase_title| - if !phase_title.phase_id.nil? then - link_to phase_title.phase.title, [:admin, phase_title.phase] - else - '-' - end - end - - actions - end - - #show details of a version - show do - attributes_table do - row :title - row :number - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row I18n.t('admin.phase'), :sortable => :phase_id do |phase_title| - if !phase_title.phase_id.nil? then - link_to phase_title.phase.title, [:admin, phase_title.phase] - end - end - row :published - row :created_at - row :updated_at - end - - end - - #sections sidebar (:organisation_id, :description, :number, :title, :version_id) - sidebar I18n.t('admin.sections'), :only => :show, :if => proc { version.sections.count >= 1} do - table_for version.sections.order("number") do |temp_phases| - column :number - column :title do |row| - link_to row.title, [:admin, row] - end - column I18n.t('admin.org_title'), :sortable => :organisation_id do |org_title| - link_to org_title.organisation.name, [:admin, org_title.organisation] - end - - end - end - - #form - form do |f| - f.inputs "Details" do - f.input :title - f.input :number - f.input :description - f.input :phase, :label => I18n.t('admin.phase_title'), - :as => :select, - :collection => Phase.order('title').map{|ph|[ph.title, ph.id]} - f.input :published - end - f.actions - end - - controller do - def permitted_params - params.permit! - end - end -end diff --git a/app/controllers/admin/annotations_controller.rb b/app/controllers/admin/annotations_controller.rb new file mode 100644 index 0000000..f0881d1 --- /dev/null +++ b/app/controllers/admin/annotations_controller.rb @@ -0,0 +1,21 @@ +module Admin + class AnnotationsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Annotation. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Annotation.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/answers_controller.rb b/app/controllers/admin/answers_controller.rb new file mode 100644 index 0000000..8960f9f --- /dev/null +++ b/app/controllers/admin/answers_controller.rb @@ -0,0 +1,21 @@ +module Admin + class AnswersController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Answer. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Answer.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb new file mode 100644 index 0000000..0018efc --- /dev/null +++ b/app/controllers/admin/application_controller.rb @@ -0,0 +1,25 @@ +# All Administrate controllers inherit from this `Admin::ApplicationController`, +# making it the ideal place to put authentication logic or other +# before_actions. +# +# If you want to add pagination or other controller-level concerns, +# you're free to overwrite the RESTful controller actions. +module Admin + class ApplicationController < Administrate::ApplicationController + before_action :authenticate_admin + + protect_from_forgery with: :exception + include Pundit + rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized + + def authenticate_admin + redirect_to root_path unless user_signed_in? && current_user.can_super_admin? + end + + # Override this value to specify the number of elements to display at a time + # on index pages. Defaults to 20. + # def records_per_page + # params[:per_page] || 20 + # end + end +end diff --git a/app/controllers/admin/exported_plans_controller.rb b/app/controllers/admin/exported_plans_controller.rb new file mode 100644 index 0000000..e4bde90 --- /dev/null +++ b/app/controllers/admin/exported_plans_controller.rb @@ -0,0 +1,21 @@ +module Admin + class ExportedPlansController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = ExportedPlan. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # ExportedPlan.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/guidance_groups_controller.rb b/app/controllers/admin/guidance_groups_controller.rb new file mode 100644 index 0000000..95d3e7c --- /dev/null +++ b/app/controllers/admin/guidance_groups_controller.rb @@ -0,0 +1,21 @@ +module Admin + class GuidanceGroupsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = GuidanceGroup. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # GuidanceGroup.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/guidances_controller.rb b/app/controllers/admin/guidances_controller.rb new file mode 100644 index 0000000..1f2495f --- /dev/null +++ b/app/controllers/admin/guidances_controller.rb @@ -0,0 +1,21 @@ +module Admin + class GuidancesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Guidance. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Guidance.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/identifier_schemes_controller.rb b/app/controllers/admin/identifier_schemes_controller.rb new file mode 100644 index 0000000..eb50d8a --- /dev/null +++ b/app/controllers/admin/identifier_schemes_controller.rb @@ -0,0 +1,21 @@ +module Admin + class IdentifierSchemesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = IdentifierScheme. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # IdentifierScheme.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/languages_controller.rb b/app/controllers/admin/languages_controller.rb new file mode 100644 index 0000000..e58baa9 --- /dev/null +++ b/app/controllers/admin/languages_controller.rb @@ -0,0 +1,21 @@ +module Admin + class LanguagesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Language. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Language.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/notes_controller.rb b/app/controllers/admin/notes_controller.rb new file mode 100644 index 0000000..db832f4 --- /dev/null +++ b/app/controllers/admin/notes_controller.rb @@ -0,0 +1,21 @@ +module Admin + class NotesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Note. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Note.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/orgs_controller.rb b/app/controllers/admin/orgs_controller.rb new file mode 100644 index 0000000..d68f358 --- /dev/null +++ b/app/controllers/admin/orgs_controller.rb @@ -0,0 +1,21 @@ +module Admin + class OrgsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Org. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Org.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/perms_controller.rb b/app/controllers/admin/perms_controller.rb new file mode 100644 index 0000000..99e9b95 --- /dev/null +++ b/app/controllers/admin/perms_controller.rb @@ -0,0 +1,21 @@ +module Admin + class PermsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Perm. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Perm.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/phases_controller.rb b/app/controllers/admin/phases_controller.rb new file mode 100644 index 0000000..de6e3c3 --- /dev/null +++ b/app/controllers/admin/phases_controller.rb @@ -0,0 +1,21 @@ +module Admin + class PhasesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Phase. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Phase.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/plan_guidance_groups_controller.rb b/app/controllers/admin/plan_guidance_groups_controller.rb new file mode 100644 index 0000000..0eeb458 --- /dev/null +++ b/app/controllers/admin/plan_guidance_groups_controller.rb @@ -0,0 +1,21 @@ +module Admin + class PlanGuidanceGroupsController < Admin::ApplicationController + # To customize the behavior of this controller, + # simply overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = PlanGuidanceGroup. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # PlanGuidanceGroup.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/plans_controller.rb b/app/controllers/admin/plans_controller.rb new file mode 100644 index 0000000..424389f --- /dev/null +++ b/app/controllers/admin/plans_controller.rb @@ -0,0 +1,21 @@ +module Admin + class PlansController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Plan. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Plan.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/question_formats_controller.rb b/app/controllers/admin/question_formats_controller.rb new file mode 100644 index 0000000..1338b69 --- /dev/null +++ b/app/controllers/admin/question_formats_controller.rb @@ -0,0 +1,21 @@ +module Admin + class QuestionFormatsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = QuestionFormat. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # QuestionFormat.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/question_options_controller.rb b/app/controllers/admin/question_options_controller.rb new file mode 100644 index 0000000..103e543 --- /dev/null +++ b/app/controllers/admin/question_options_controller.rb @@ -0,0 +1,21 @@ +module Admin + class QuestionOptionsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = QuestionOption. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # QuestionOption.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/questions_controller.rb b/app/controllers/admin/questions_controller.rb new file mode 100644 index 0000000..be5d2a7 --- /dev/null +++ b/app/controllers/admin/questions_controller.rb @@ -0,0 +1,21 @@ +module Admin + class QuestionsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Question. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Question.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/regions_controller.rb b/app/controllers/admin/regions_controller.rb new file mode 100644 index 0000000..6e5627b --- /dev/null +++ b/app/controllers/admin/regions_controller.rb @@ -0,0 +1,21 @@ +module Admin + class RegionsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Region. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Region.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb new file mode 100644 index 0000000..748c165 --- /dev/null +++ b/app/controllers/admin/roles_controller.rb @@ -0,0 +1,21 @@ +module Admin + class RolesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Role. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Role.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/sections_controller.rb b/app/controllers/admin/sections_controller.rb new file mode 100644 index 0000000..3b94a0a --- /dev/null +++ b/app/controllers/admin/sections_controller.rb @@ -0,0 +1,21 @@ +module Admin + class SectionsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Section. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Section.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/splash_logs_controller.rb b/app/controllers/admin/splash_logs_controller.rb new file mode 100644 index 0000000..aa3fa22 --- /dev/null +++ b/app/controllers/admin/splash_logs_controller.rb @@ -0,0 +1,21 @@ +module Admin + class SplashLogsController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = SplashLog. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # SplashLog.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/templates_controller.rb b/app/controllers/admin/templates_controller.rb new file mode 100644 index 0000000..8ac79e1 --- /dev/null +++ b/app/controllers/admin/templates_controller.rb @@ -0,0 +1,21 @@ +module Admin + class TemplatesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Template. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Template.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb new file mode 100644 index 0000000..9617c6c --- /dev/null +++ b/app/controllers/admin/themes_controller.rb @@ -0,0 +1,21 @@ +module Admin + class ThemesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = Theme. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # Theme.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/token_permission_types_controller.rb b/app/controllers/admin/token_permission_types_controller.rb new file mode 100644 index 0000000..37b3487 --- /dev/null +++ b/app/controllers/admin/token_permission_types_controller.rb @@ -0,0 +1,21 @@ +module Admin + class TokenPermissionTypesController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = TokenPermissionType. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # TokenPermissionType.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/user_identifiers_controller.rb b/app/controllers/admin/user_identifiers_controller.rb new file mode 100644 index 0000000..bdf5faa --- /dev/null +++ b/app/controllers/admin/user_identifiers_controller.rb @@ -0,0 +1,21 @@ +module Admin + class UserIdentifiersController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = UserIdentifier. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # UserIdentifier.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb new file mode 100644 index 0000000..70251c0 --- /dev/null +++ b/app/controllers/admin/users_controller.rb @@ -0,0 +1,21 @@ +module Admin + class UsersController < Admin::ApplicationController + # To customize the behavior of this controller, + # you can overwrite any of the RESTful actions. For example: + # + # def index + # super + # @resources = User. + # page(params[:page]). + # per(10) + # end + + # Define a custom finder by overriding the `find_resource` method: + # def find_resource(param) + # User.find_by!(slug: param) + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/annotations_controller.rb b/app/controllers/annotations_controller.rb new file mode 100644 index 0000000..e83366b --- /dev/null +++ b/app/controllers/annotations_controller.rb @@ -0,0 +1,116 @@ +class AnnotationsController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create annotations + def admin_create + # authorize the question (includes to reduce queries) + @question = Question.includes(section: { phase: :template}).find(params[:question_id]) + authorize @question + if params[:example_answer_text].present? + example_answer = init_annotation(params[:example_answer_text], @question, current_user.org, Annotation.types[:example_answer]) + end + if params[:guidance_text].present? + guidance = init_annotation(params[:guidance_text], @question, current_user.org, Annotation.types[:guidance]) + end + # if they dont exist, no requirement for them to be saved + ex_save = example_answer.present? ? example_answer.save : true + guid_save = guidance.present? ? guidance.save : true + + if ex_save && guid_save + redirect_to admin_show_phase_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully created.') + else + @section = @question.section + @phase = @section.phase + @open = true + @sections = @phase.sections + @section_id = @section.id + @question_id = @example_answer.question + if !ex_save && !guid_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + '\n' + + failed_create_error(gudiance, _('guidance')) + elsif !guid_save + flash[:notice] = failed_create_error(gudiance, _('guidance')) + elsif !ex_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + end + render "phases/admin_show" + end + end + + + #update a example answer of a template + def admin_update + @question = Question.includes(section: { phase: :template}).find(params[:question_id]) + if params[:guidance_id].present? + guidance = Annotation.includes(question: {section: {phase: :template}}).find(params[:guidance_id]) + authorize guidance + end + if params[:example_answer_id].present? + example_answer = Annotation.includes(question: {section: {phase: :template}}).find(params[:example_answer_id]) + authorize example_answer + end + verify_authorized + # if guidance present, update + if params[:guidance_text].present? + if guidance.present? + guidance.text = params[:guidance_text] + else + guidance = init_annotation(params[:guidance_text], @question, current_user.org, Annotation.types[:guidance]) + end + end + # if example answer present, update + if params[:example_answer_text].present? + if example_answer.present? + example_answer.text = params[:example_answer_text] + else + example_answer = init_annotation(params[:example_answer_text], @question, current_user.org, Annotation.types[:example_answer]) + end + end + # only required to save if we updated/created one + ex_save = example_answer.present? ? example_answer.save : true + guid_save = guidance.present? ? guidance.save : true + + @section = @question.section + @phase = @section.phase + if ex_save && guid_save + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully updated.') + else + if !ex_save && !guid_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + '\n' + + failed_create_error(gudiance, _('guidance')) + elsif !guid_save + flash[:notice] = failed_create_error(gudiance, _('guidance')) + elsif !ex_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + end + render action: "phases/admin_show" + end + end + + #delete an annotation + def admin_destroy + @example_answer = Annotation.includes(question: { section: {phase: :template}}).find(params[:id]) + authorize @example_answer + @question = @example_answer.question + @section = @question.section + @phase = @section.phase + if @example_answer.destroy + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: _('Information was successfully deleted.') + else + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: flash[:notice] = failed_destroy_error(@example_answer, _('example answer')) + end + end + + private + + def init_annotation(text, question, org, type) + annotation = Annotation.new + annotation.org = org + annotation.question = question + annotation.text = text + annotation.type = type + return annotation + end + +end \ No newline at end of file diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index e157e76..7d48ddf 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -1,37 +1,55 @@ class AnswersController < ApplicationController after_action :verify_authorized + respond_to :html - # POST /answers - def create - @answer = Answer.new(params[:answer]) - authorize @answer - old_answer = @answer.plan.answer(@answer.question_id, false) - proceed = false - @answer.text = params["answer-text-#{@answer.question_id}".to_sym] - if (old_answer.nil? && @answer.text != "") || ((!old_answer.nil?) && (old_answer.text != @answer.text)) then - proceed = true - end - - if (@answer.question.question_format.title == I18n.t("helpers.checkbox") || - @answer.question.question_format.title == I18n.t("helpers.multi_select_box") || - @answer.question.question_format.title == I18n.t("helpers.radio_buttons") || - @answer.question.question_format.title == I18n.t("helpers.dropdown")) then - if (old_answer.nil? && @answer.option_ids.count > 0) || ((!old_answer.nil?) && (old_answer.option_ids - @answer.option_ids).count != 0 && (@answer.option_ids - old_answer.option_ids).count != 0) then - proceed = true - end - end - if proceed - respond_to do |format| - if @answer.save - format.html { redirect_to :back, status: :found, notice: I18n.t('helpers.project.answer_recorded') } - else - format.html { redirect_to :back, notice: I18n.t('helpers.project.answer_error') } - end - end - else - respond_to do |format| - format.html { redirect_to :back, notice: I18n.t('helpers.project.answer_no_change') } - end - end - end -end \ No newline at end of file + # PUT/PATCH /answers/[:id] + def update + p_params = permitted_params() + @answer = Answer.find_by({plan_id: p_params[:plan_id], question_id: p_params[:question_id], }) + begin + if @answer + authorize @answer + @answer.update(p_params) + if p_params[:question_option_ids].present? + @answer.touch() # Saves the record with the updated_at set to the current time. Needed if only answer.question_options is updated + end + else + @answer = Answer.new(p_params) + @answer.lock_version = 1 + authorize @answer + @answer.save() # NOTE, there is a chance to create multiple answer associated for a plan/question (IF any concurrent thread) INSERTS an answer after checking the existence of an answer (Line 8) + # In order to avoid that edge-case, it is recommended to create answers whenever a new plan is created (e.g. after_create callback) + end + rescue ActiveRecord::StaleObjectError + @stale_answer = @answer + @answer = Answer.find_by({plan_id: p_params[:plan_id], question_id: p_params[:question_id]}) + end + + @plan = Plan.includes({ + sections: { + questions: [ + :answers, + :question_format + ] + } + }).find(p_params[:plan_id]) + @question = @answer.question + @section = @plan.get_section(@question.section_id) + + respond_to do |format| + format.js {} + end + end # End update + + private + def permitted_params + permitted = params.require(:answer).permit(:id, :text, :plan_id, :user_id, :question_id, :lock_version, :question_option_ids => []) + if !params[:answer][:question_option_ids].nil? && !permitted[:question_option_ids].present? #If question_option_ids has been filtered out because it was a scalar value (e.g. radiobutton answer) + permitted[:question_option_ids] = [params[:answer][:question_option_ids]] # then convert to an Array + end + if !permitted[:id].present? + permitted.delete(:id) + end + return permitted + end # End permitted_params +end diff --git a/app/controllers/api/v0/base_controller.rb b/app/controllers/api/v0/base_controller.rb index 7e939fd..c8edddd 100644 --- a/app/controllers/api/v0/base_controller.rb +++ b/app/controllers/api/v0/base_controller.rb @@ -117,28 +117,9 @@ def render_bad_credentials self.headers['WWW-Authenticate'] = "Token realm=\"\"" - render json: I18n.t("api.bad_credentials"), status: 401 + render json: _("Bad Credentials"), status: 401 end - def has_auth (auth_type) - auth = false - # not sure if initial if is necissary, but it works with it there... refactor later? - # if !TokenPermission.where(api_token: @token).nil? - # TokenPermission.where(api_token: @token).find_each do |permission| - # if permission.token_permission_type.token_type == auth_type - # auth = true - # logger.info "we have auth" - # end - # end - # end - OrgTokenPermission.where(organisation_id: @user.organisation_id).find_each do |org_token_permission| - logger.debug "#{org_token_permission.token_permission_type.token_type}" - if org_token_permission.token_permission_type.token_type == auth_type - auth= true - end - end - return auth - end end end diff --git a/app/controllers/api/v0/dmptemplates_controller.rb b/app/controllers/api/v0/dmptemplates_controller.rb deleted file mode 100644 index 0e0a256..0000000 --- a/app/controllers/api/v0/dmptemplates_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Api - module V0 - class DmptemplatesController < Api::V0::BaseController - before_action :authenticate - - - ## - # GET - # @return a list of templates ordered by organisation - def index - # check if the user has permissions to use the templates API - if has_auth(constant("api_endpoint_types.templates")) - @all_templates = Dmptemplate.all - respond_with @all_templates - else - #render unauthorised - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end - - end - end - end -end \ No newline at end of file diff --git a/app/controllers/api/v0/guidance_groups_controller.rb b/app/controllers/api/v0/guidance_groups_controller.rb index a22c9b2..65899b9 100644 --- a/app/controllers/api/v0/guidance_groups_controller.rb +++ b/app/controllers/api/v0/guidance_groups_controller.rb @@ -2,29 +2,16 @@ module V0 class GuidanceGroupsController < Api::V0::BaseController before_action :authenticate - - def show - # check if the user has permission to use the guidances api - if has_auth(constant("api_endpoint_types.guidances")) - # determine if they have authorization to view this guidance group - if GuidanceGroup.can_view?(@user, params[:id]) - respond_with get_resource - else - render json: I18n.t("api.bad_resource"), status: 401 - end - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end - end + #after_action :verify_authorized def index - if has_auth(constant("api_endpoint_types.guidances")) - @all_viewable_groups = GuidanceGroup.all_viewable(@user) - respond_with @all_viewable_groups - else - #render unauthorised - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end + raise Pundit::NotAuthorizedError unless Api::V0::GuidanceGroupPolicy.new(@user, :guidance_group).index? + @all_viewable_groups = GuidanceGroup.all_viewable(@user) + respond_with @all_viewable_groups + end + + def pundit_user + return @user end diff --git a/app/controllers/api/v0/guidances_controller.rb b/app/controllers/api/v0/guidances_controller.rb deleted file mode 100644 index 2803ea6..0000000 --- a/app/controllers/api/v0/guidances_controller.rb +++ /dev/null @@ -1,59 +0,0 @@ -module Api - module V0 - class GuidancesController < Api::V0::BaseController - before_action :authenticate - - swagger_controller :guidances, 'Guidances' - - swagger_api :show do - summary 'Returns a single guidance item' - notes 'Notes...' - param :path, :id, :integer, :required, "Guidance Id" - param :header, 'Authentication-Token', :string, :required, 'Authentication-Token' - response :ok, "success", :Guidance - response :unauthorized - response :not_found - end - - # TODO: impliment auth on show/index - # for both, first validate that the user has the permission to use this api - # then for show, display iff they have permissions for that resource - # for index, compile the list of all groups they have permissions to view, then return - - def show - # ensure use has auth for guidances api - if has_auth("guidance") - if Guidance.can_view?(@user, params[:id]) - respond_with get_resource - else - render json: I18n.t("api.bad_resource"), status: 401 - end - else - render I18n.t("api.no_auth_for_endpoint"), status: 401 - end - end - - swagger_api :index do - summary 'Returns a list of all viewable guidances' - notes 'Notes...' - param :header, 'Authentication-Token', :string, :required, 'Authentication-Token' - response :unauthorized - end - - def index - if has_auth("guidance") - @all_viewable_guidances = Guidance.all_viewable(@user) - respond_with @all_viewable_guidances - else - render json I18n.t("api.no_auth_for_endpoint"), status: 401 - end - end - - - private - def query_params - params.permit(:id) - end - end - end -end diff --git a/app/controllers/api/v0/plans_controller.rb b/app/controllers/api/v0/plans_controller.rb new file mode 100644 index 0000000..23ae557 --- /dev/null +++ b/app/controllers/api/v0/plans_controller.rb @@ -0,0 +1,48 @@ +module Api + module V0 + class PlansController < Api::V0::BaseController + before_action :authenticate + + ## + # Creates a new plan based on the information passed in JSON to the API + def create + @template = Template.live(params[:template_id]) + raise Pundit::NotAuthorizedError unless Api::V0::PlansPolicy.new(@user, @template).create? + + plan_user = User.find_by(email: params[:plan][:email]) + # ensure user exists + if plan_user.blank? + User.invite!({email: params[:plan][:email]}, ( @user)) + plan_user = User.find_by(email: params[:plan][:email]) + plan_user.org = @user.org + plan_user.save + end + # ensure user's organisation is the same as api user's + raise Pundit::NotAuthorizedError, _("user must be in your organisation") unless plan_user.org == @user.org + + # initialize the plan + @plan = Plan.new + @plan.principal_investigator = plan_user.surname.blank? ? nil : "#{plan_user.firstname} #{plan_user.surname}" + @plan.data_contact = plan_user.email + # set funder name to template's org, or original template's org + if @template.customization_of.nil? + @plan.funder_name = @template.org.name + else + @plan.funder_name = Template.where(dmptemplate_id: @template.customization_of).first.org.name + end + @plan.template = @template + @plan.title = params[:plan][:title] + if @plan.save + @plan.assign_creator(plan_user) + respond_with @plan + else + # the plan did not save + self.headers['WWW-Authenticate'] = "Token realm=\"\"" + render json: _("Bad Parameters"), status: 400 + end + end + + + end + end +end diff --git a/app/controllers/api/v0/projects_controller.rb b/app/controllers/api/v0/projects_controller.rb deleted file mode 100644 index 47bae8d..0000000 --- a/app/controllers/api/v0/projects_controller.rb +++ /dev/null @@ -1,104 +0,0 @@ -module Api - module V0 - class ProjectsController < Api::V0::BaseController - before_action :authenticate - - swagger_controller :projects, 'Plans' - - swagger_api :create do |api| - summary 'Returns a single guidance group item' - notes 'Notes...' - param :header, 'Authentication-Token', :string, :required, 'Authentication-Token' - response :unauthorized - response :not_found - end - - ## - # Creates a new project based on the information passed in JSON to the API - def create - # find the user's api_token permissions - # then ensure that they have the permission associated with creating plans - if has_auth(constant("api_endpoint_types.plans")) - #params[:organization_id] = Organisation.where(name: params[:template][:organization]) - # find_by returns nil if none found, find_by! raises an ActiveRecord error - organization = Organisation.find_by name: params[:template][:organisation] - - # if organization exists - if !organization.nil? - # if organization is funder - if organization.organisation_type == (OrganisationType.find_by(name: constant("organisation_types.funder"))) - # if organization has only 1 template - if organization.dmptemplates.length == 1 - # set template id - dmptemplate = organization.dmptemplates.first - # else if params.template.name specified && params.template.name == one of organization's tempates - elsif !organization.dmptemplates.find_by title: params[:template][:name].nil? - # set template id - dmptemplate = organization.templates.find_by title: params[:template][:name] - # else error: organization has more than one template and template name unspecified - else - render json: I18n.t("api.org_multiple_templates"), status: 400 and return - end - # else error: organization specified is not a funder - else - render json: I18n.t("api.org_not_funder"), status: 400 and return - end - # else error: organization does not exist - else - render json: I18n.t("api.org_dosent_exist"), status: 400 and return - end - - all_groups = [] - # Check to see if the user specified guidances - if !params[:guidance].nil? - # for each specified guidance, see if it exists - params[:guidance][:name].each do |guidance_name| - group = GuidanceGroup.find_by(name: guidance_name) - # if it exists, add it to the guidances for the new project - if !group.nil? - all_groups = all_groups + [group] - end - end - end - - # cant invite a user without having a current user because of devise :ivitable - # after we have auth, will be able to assign an :invited_by_id - user = User.find_by email: params[:project][:email] - # if user does not exist - if user.nil? - # invite user to DMPRoadmap - User.invite!({email: params[:project][:email]}, ( @user)) - # set project owner to user associated w/email - user = (User.find_by email: params[:project][:email]) - end - - # create new project with specified parameters - @project = Project.new - @project.title = params[:project][:title] - @project.dmptemplate = dmptemplate - @project.slug = params[:project][:title] - @project.organisation = @user.organisations.first - @project.assign_creator(user.id) - @project.guidance_groups = all_groups - - # if save successful, render success, otherwise show error - if @project.save - #render json: @project ,status: :created - render :show, status: :created - else - render json: get_resource.errors, status: :unprocessable_entity - end - else - - render json: I18n.t("api.no_auth_for_endpoint"), status: 400 and return - end - end - - # private - # def project_params - # params.require(:template).permit(:organisation, :name) - # params.require(:project).permit(:title, :email) - # end - end - end -end diff --git a/app/controllers/api/v0/statistics_controller.rb b/app/controllers/api/v0/statistics_controller.rb index ec21140..b3b95a4 100644 --- a/app/controllers/api/v0/statistics_controller.rb +++ b/app/controllers/api/v0/statistics_controller.rb @@ -8,19 +8,16 @@ # @return a count of users who joined DMPonline between the optional specified dates # users are scoped to the organisation of the user initiating the call def users_joined - if has_auth(constant("api_endpoint_types.statistics")) - users = restrict_date_range(@user.organisations.first.users) - confirmed_users = [] - users.each do |user| - unless user.confirmed_at.blank? - confirmed_users += [user] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).users_joined? + users = restrict_date_range(@user.org.users) + confirmed_users = [] + users.each do |user| + unless user.confirmed_at.blank? + confirmed_users += [user] end - @users_count = confirmed_users.count - respond_with @users_count - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + @users_count = confirmed_users.count + respond_with @users_count end @@ -29,17 +26,26 @@ # @return the number of DMPs using the specified template between the optional specified dates # ensures that the template is owned/created by the caller's organisation def using_template - if has_auth(constant("api_endpoint_types.statistics")) - template = Dmptemplate.find(params[:id]) - if template.organisation == @user.organisations.first - @template_count = restrict_date_range(template.projects).count - respond_with @template_count + org_templates = @user.org.templates.where(customization_of: nil) + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, org_templates.first).using_template? + @templates = {} + org_templates.each do |template| + if @templates[template.title].blank? + @templates[template.title] = {} + @templates[template.title][:title] = template.title + @templates[template.title][:id] = template.dmptemplate_id + if template.plans.present? + @templates[template.title][:uses] = restrict_date_range(template.plans).length + else + @templates[template.title][:uses] = 0 + end else - #no auth to view statistics for this template + if template.plans.present? + @templates[template.title][:uses] += restrict_date_range(template.plans).length + end end - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + respond_with @templates end ## @@ -48,20 +54,29 @@ # the uses are restricted to DMPs created by users of the same organisation # as the user who ititiated the call def plans_by_template - if has_auth(constant("api_endpoint_types.statistics")) - @org_projects = [] - @user.organisations.first.users.each do |user| - user.projects.each do |project| - unless @org_projects.include? project - @org_projects += [project] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).plans_by_template? + org_projects = [] + @user.org.users.each do |user| + user.plans.each do |plan| + unless org_projects.include? plan + org_projects += [plan] end end - @org_projects = restrict_date_range(@org_projects) - respond_with @org_projects - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + org_projects = restrict_date_range(org_projects) + @templates = {} + org_projects.each do |plan| + # if hash exists + if @templates[plan.template.title].blank? + @templates[plan.template.title] = {} + @templates[plan.template.title][:title] = plan.template.title + @templates[plan.template.title][:id] = plan.template.dmptemplate_id + @templates[plan.template.title][:uses] = 1 + else + @templates[plan.template.title][:uses] += 1 + end + end + respond_with @templates end ## @@ -70,20 +85,17 @@ # DMPs must be owned by a user who's organisation is the same as the user # who generates the call def plans - if has_auth(constant("api_endpoint_types.statistics")) - @org_projects = [] - @user.organisations.first.users.each do |user| - user.projects.each do |project| - unless @org_projects.include? project - @org_projects += [project] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).plans? + @org_plans = [] + @user.org.users.each do |user| + user.plans.each do |plan| + unless @org_plans.include? plan + @org_plans += [plan] end end - @org_projects = restrict_date_range(@org_projects) - respond_with @org_projects - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + @org_plans = restrict_date_range(@org_plans) + respond_with @org_plans end diff --git a/app/controllers/api/v0/templates_controller.rb b/app/controllers/api/v0/templates_controller.rb new file mode 100644 index 0000000..8560068 --- /dev/null +++ b/app/controllers/api/v0/templates_controller.rb @@ -0,0 +1,47 @@ +module Api + module V0 + class TemplatesController < Api::V0::BaseController + before_action :authenticate + + + ## + # GET + # @return a list of templates ordered by organisation + def index + # check if the user has permissions to use the templates API + raise Pundit::NotAuthorizedError unless Api::V0::TemplatePolicy.new(@user, :guidance_group).index? + + @org_templates = {} + + published_templates = Template.includes(:org).valid.where(customization_of: nil, published: true).order(:org_id, :version) + customized_templates = Template.includes(:org).valid.where(org_id: @user.org_id, published: true).where.not(customization_of: nil) + + published_templates.each do |temp| + if @org_templates[temp.org].present? + if @org_templates[temp.org][:own][temp.dmptemplate_id].nil? + @org_templates[temp.org][:own][temp.dmptemplate_id] = temp + end + else + @org_templates[temp.org] = {} + @org_templates[temp.org][:own] = {} + @org_templates[temp.org][:cust] = {} + @org_templates[temp.org][:own][temp.dmptemplate_id] = temp + end + end + customized_templates.each do |temp| + if @org_templates[temp.org].present? + if @org_templates[temp.org][:cust][temp.dmptemplate_id].nil? + @org_templates[temp.org][:cust][temp.dmptemplate_id] = temp + end + else + @org_templates[temp.org] = {} + @org_templates[temp.org][:own] = {} + @org_templates[temp.org][:cust] = {} + @org_templates[temp.org][:cust][temp.dmptemplate_id] = temp + end + end + respond_with @org_templates + 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 b2f7983..a1ff6ad 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -8,52 +8,42 @@ include Pundit helper_method GlobalHelpers.instance_methods - # Override build_footer method in ActiveAdmin::Views::Pages - require 'active_admin_views_pages_base.rb' rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized def user_not_authorized - redirect_to root_url, alert: I18n.t('unauthorized') - end - - before_filter :set_locale - - after_filter :store_location - - def set_locale - # parameter from url takes precedence - # check if locale is defined - if params[:locale] # and I18n.available_locales.include? params[:locale] # throw an error if not available - # if locales data is present in the parameter from url use it - I18n.locale = params[:locale] - - elsif user_signed_in? and !current_user[:language_id].nil? - I18n.locale = Language.find_by_id(current_user[:language_id]).abbreviation - # if user has set preferred language use it - - elsif user_signed_in? and current_user.organisation.present? and !current_user.organisation[:language_id].nil? - I18n.locale = Language.find_by_id(current_user.organisation[:language_id]).abbreviation - # use user's organization language, keep in mine the "OTHER ORG" edge case which should use default language - + if user_signed_in? + redirect_to plans_url, notice: _('You are not authorized to perform this action.') else - # just use the default language, line can be commented out, included just for clarity - I18n.locale = I18n.default_locale + redirect_to root_url, alert: _('You need to sign in or sign up before continuing.') end end - # Added setting for passing local params across pages - def default_url_options(options = {}) - { locale: I18n.locale }.merge options + before_filter :set_gettext_locale + + after_filter :store_location + + # Sets FastGettext locale for every request made + def set_gettext_locale + FastGettext.locale = session[:locale] || FastGettext.default_locale + end + + # PATCH /locale/:locale REST method + def set_locale_session + if FastGettext.default_available_locales.include?(params[:locale]) + session[:locale] = params[:locale] + end + redirect_to root_path end def store_location # store last url - this is needed for post-login redirect to whatever the user last visited. - if (request.fullpath != "/users/sign_in" && \ - request.fullpath != "/users/sign_up" && \ - request.fullpath != "/users/password" && \ - request.fullpath != "/users/sign_up?nosplash=true" && \ - !request.xhr?) # don't store ajax calls + unless ["/users/sign_in", + "/users/sign_up", + "/users/password", + "/users/invitation/accept", + ].any? { |ur| request.fullpath.include?(ur) } \ + or request.xhr? # don't store ajax calls session[:previous_url] = request.fullpath end end @@ -79,23 +69,16 @@ redirect_to root_path unless user_signed_in? && (current_user.can_add_orgs? || current_user.can_change_org? || current_user.can_super_admin?) end - def get_plan_list_columns - if user_signed_in? - @selected_columns = current_user.settings(:plan_list).columns + def failed_create_error(obj, obj_name) + "#{_('Could not create your %{o}.') % {o: obj_name}} #{errors_to_s(obj)}" + end - # handle settings saved and stored using an older version of the settings gem - if @selected_columns.kind_of? Hash - unless @selected_columns['elements'].nil? - @selected_columns = @selected_columns['elements'].collect{|k,v| puts "#{k} - #{v}"; k} - end - end - - # If the settings are missing or stored in the wrong format for some reason - # then use the defaults columns - @selected_columns = Settings::PlanList::DEFAULT_COLUMNS if @selected_columns.empty? - - @all_columns = Settings::PlanList::ALL_COLUMNS - end + def failed_update_error(obj, obj_name) + "#{_('Could not update your %{o}.') % {o: obj_name}} #{errors_to_s(obj)}" + end + + def failed_destroy_error(obj, obj_name) + "#{_('Could not delete the %{o}.') % {o: obj_name}} #{errors_to_s(obj)}" end private @@ -109,4 +92,32 @@ def prepend_view_paths prepend_view_path "app/views/branded" end + + def errors_to_s(obj) + if obj.errors.count > 0 + msg = "
" + obj.errors.each do |e,m| + if m.include?('empty') || m.include?('blank') + msg += "#{_(e)} - #{_(m)}
" + else + msg += "'#{obj[e]}' - #{_(m)}
" + end + end + msg + end + end + + ## + # Sign out of Shibboleth SP local session too. + # ------------------------------------------------------------- + def after_sign_out_path_for(resource_or_scope) + if Rails.application.config.shibboleth_enabled + return Rails.application.config.shibboleth_logout_url + root_url + super + else + super + end + end + # ------------------------------------------------------------- + end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb deleted file mode 100644 index 87838cb..0000000 --- a/app/controllers/comments_controller.rb +++ /dev/null @@ -1,61 +0,0 @@ -class CommentsController < ApplicationController - after_action :verify_authorized - - # POST /comments - def create - @comment = Comment.new(params[:new_comment]) - @comment.text = params["#{params[:new_comment][:question_id]}new_comment_text"] - @comment.question_id = params[:new_comment][:question_id] - @comment.user_id = params[:new_comment][:user_id] - @comment.plan_id = params[:new_comment][:plan_id] - authorize @comment - - @plan = Plan.find(@comment.plan_id) - @project = Project.find(@plan.project_id) - - respond_to do |format| - if @comment.save - session[:question_id_comments] = @comment.question_id - format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.comment_created") } - end - end - end - - # PUT /comments/1 - def update - @comment = Comment.find(params[:comment][:id]) - authorize @comment - @comment.text = params["#{params[:comment][:id]}_comment_text"] - - @plan = Plan.find(@comment.plan_id) - @project = Project.find(@plan.project_id) - - respond_to do |format| - if @comment.update_attributes(params[:comment]) - session[:question_id_comments] = @comment.question_id - format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.comment_updated") } - end - end - end - - # ARCHIVE /comments/1 - # ARCHIVE /comments/1.json - def archive - @comment = Comment.find(params[:comment][:id]) - authorize @comment - @comment.archived = true - @comment.archived_by = params[:comment][:archived_by] - - @plan = Plan.find(@comment.plan_id) - @project = Project.find(@plan.project_id) - - respond_to do |format| - if @comment.update_attributes(params[:comment]) - session[:question_id_comments] = @comment.question_id - format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.comment_removed") } - end - end - end - - -end diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb deleted file mode 100644 index 8070b25..0000000 --- a/app/controllers/confirmations_controller.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ConfirmationsController < Devise::ConfirmationsController - - protected - - def after_confirmation_path_for(resource_name, resource) - root_path - end - -end \ No newline at end of file diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb deleted file mode 100644 index ae9e85a..0000000 --- a/app/controllers/contacts_controller.rb +++ /dev/null @@ -1,33 +0,0 @@ -class ContactsController < ContactUs::ContactsController - - # in order to i18 this file recaptcha gem has to be updated - - def create - @contact = ContactUs::Contact.new(params[:contact_us_contact]) - if (!user_signed_in?) - if verify_recaptcha(:message => "You have not added the validation words correctly") && @contact.save - flash[:notice] = t('contact_us.notices.success') - if user_signed_in? then - redirect_to :controller => 'projects', :action => 'index' - else - redirect_to(root_path) - end - else - flash[:alert] = t('contact_us.notices.error') - render_new_page - end - else - if @contact.save - flash[:notice] = t('contact_us.notices.success') - if user_signed_in? then - redirect_to :controller => 'projects', :action => 'index' - else - redirect_to(root_path) - end - else - flash[:alert] = t('contact_us.notices.error') - render_new_page - end - end - end -end \ No newline at end of file diff --git a/app/controllers/dmptemplates_controller.rb b/app/controllers/dmptemplates_controller.rb deleted file mode 100644 index 9c7f757..0000000 --- a/app/controllers/dmptemplates_controller.rb +++ /dev/null @@ -1,450 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] This controller is responsible for all the actions in the admin interface under templates (e.g. phases, versions, sections, questions, suggested answer) (index; show; create; edit; delete) -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -class DmptemplatesController < ApplicationController - after_action :verify_authorized - - # GET /dmptemplates - def admin_index - authorize Dmptemplate - #institutional templates - @dmptemplates_own = Dmptemplate.own_institutional_templates(current_user.organisation_id) - #funders templates - @dmptemplates_funders = Dmptemplate.funders_templates - respond_to do |format| - format.html # index.html.erb - end - end - - # GET /dmptemplates/1 - def admin_template - @dmptemplate = Dmptemplate.find(params[:id]) - authorize @dmptemplate - respond_to do |format| - format.html # show.html.erb - end - end - - - - # PUT /dmptemplates/1 - def admin_update - @dmptemplate = Dmptemplate.find(params[:id]) - authorize @dmptemplate - @dmptemplate.description = params["template-desc"] - respond_to do |format| - if @dmptemplate.update_attributes(params[:dmptemplate]) - format.html { redirect_to admin_template_dmptemplate_path(params[:dmptemplate]), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "edit" } - end - end - end - - - # GET /dmptemplates/new - def admin_new - @dmptemplate = Dmptemplate.new - authorize @dmptemplate - respond_to do |format| - format.html # new.html.erb - end - end - - # POST /dmptemplates - def admin_create - @dmptemplate = Dmptemplate.new(params[:dmptemplate]) - @dmptemplate.organisation_id = current_user.organisation.id - @dmptemplate.description = params['template-desc'] - authorize @dmptemplate - respond_to do |format| - if @dmptemplate.save - format.html { redirect_to admin_template_dmptemplate_path(@dmptemplate), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_new" } - end - end - end - - - - # DELETE /dmptemplates/1 - def admin_destroy - @dmptemplate = Dmptemplate.find(params[:id]) - authorize @dmptemplate - @dmptemplate.destroy - respond_to do |format| - format.html { redirect_to admin_index_dmptemplate_path } - end - end - - - - # PHASES - - #show and edit a phase of the template - def admin_phase - @phase = Phase.find(params[:id]) - authorize @phase.dmptemplate - if !params.has_key?(:version_id) then - @edit = 'false' - #check for the most recent published version, if none is available then return the most recent one - versions = @phase.versions.where('published = ?', true).order('updated_at DESC') - if versions.any?() then - @version = versions.first - else - @version = @phase.versions.order('updated_at DESC').first - end - # When the version_id is passed as an argument - else - @edit = params[:edit] - @version = Version.find(params[:version_id]) - end - #verify if there are any sections if not create one - @sections = @version.sections - if !@sections.any?() || @sections.count == 0 then - @section = @version.sections.build - @section.title = '' - @section.version_id = params[:version_id] - @section.number = 1 - @section.organisation_id = current_user.organisation.id - @section.published = true - @section.save - @new_sec = true - end - #verify if section_id has been passed, if so then open that section - if params.has_key?(:section_id) then - @open = true - @section_id = params[:section_id].to_i - end - if params.has_key?(:question_id) then - @question_id = params[:question_id].to_i - end - respond_to do |format| - format.html - end - end - - - #preview a phase - def admin_previewphase - @version = Version.find(params[:id]) - authorize @version.phase.dmptemplate - respond_to do |format| - format.html - end - end - - - #add a new phase to a template - def admin_addphase - @dmptemplate = Dmptemplate.find(params[:id]) - @phase = Phase.new - authorize @dmptemplate - if @dmptemplate.phases.count == 0 then - @phase.number = '1' - else - @phase.number = @dmptemplate.phases.count + 1 - end - respond_to do |format| - format.html - end - end - - - #create a phase - def admin_createphase - @phase = Phase.new(params[:phase]) - authorize @phase.dmptemplate - @phase.description = params["phase-desc"] - @version = @phase.versions.build - @version.title = "#{@phase.title} v.1" - @version.phase_id = @phase.id - @version.number = 1 - @version.published = false - respond_to do |format| - if @phase.save - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - - #update a phase of a template - def admin_updatephase - @phase = Phase.find(params[:id]) - authorize @phase.dmptemplate - @phase.description = params["phase-desc"] - respond_to do |format| - if @phase.update_attributes(params[:phase]) - format.html { redirect_to admin_phase_dmptemplate_path(@phase), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #delete a version, sections and questions - def admin_destroyphase - @phase = Phase.find(params[:phase_id]) - authorize @phase.dmptemplate - @dmptemplate = @phase.dmptemplate - @phase.destroy - respond_to do |format| - format.html { redirect_to admin_template_dmptemplate_path(@dmptemplate), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - -# VERSIONS - - #update a version of a template - def admin_updateversion - @version = Version.find(params[:id]) - authorize @version.phase.dmptemplate - @version.description = params["version-desc"] - @phase = @version.phase - if @version.published && !@phase.dmptemplate.published then - @phase.dmptemplate.published = true - end - if @version.published == true then - @all_versions = @phase.versions.where('published = ?', true) - @all_versions.each do |v| - if v.id != @version.id && v.published == true then - v.published = false - v.save - end - end - end - respond_to do |format| - if @version.update_attributes(params[:version]) - format.html { redirect_to admin_phase_dmptemplate_path(@phase, :version_id => @version.id, :edit => 'false'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #clone a version of a template - def admin_cloneversion - @old_version = Version.find(params[:version_id]) - authorize @old_version.phase.dmptemplate - @version = @old_version.amoeba_dup - @phase = @version.phase - respond_to do |format| - if @version.save - format.html { redirect_to admin_phase_dmptemplate_path(@phase, :version_id => @version.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #delete a version, sections and questions - def admin_destroyversion - @version = Version.find(params[:version_id]) - authorize @version.phase.dmptemplate - @phase = @version.phase - @version.destroy - respond_to do |format| - format.html { redirect_to admin_phase_dmptemplate_path(@phase), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - - -# SECTIONS - #create a section - def admin_createsection - @section = Section.new(params[:section]) - authorize @section.version.phase.dmptemplate - @section.description = params["section-desc"] - respond_to do |format| - if @section.save - format.html { redirect_to admin_phase_dmptemplate_path(:id => @section.version.phase_id, :version_id => @section.version_id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - - #update a section of a template - def admin_updatesection - @section = Section.find(params[:id]) - authorize @section.version.phase.dmptemplate - @section.description = params["section-desc-#{params[:id]}"] - @version = @section.version - @phase = @version.phase - respond_to do |format| - if @section.update_attributes(params[:section]) - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id , :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - - #delete a section and questions - def admin_destroysection - @section = Section.find(params[:section_id]) - authorize @section.version.phase.dmptemplate - @version = @section.version - @phase = @version.phase - @section.destroy - respond_to do |format| - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :edit => 'true' ), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - - -# QUESTIONS - - #create a question - def admin_createquestion - @question = Question.new(params[:question]) - authorize @question.section.version.phase.dmptemplate - @question.guidance = params["new-question-guidance"] - @question.default_value = params["new-question-default-value"] - respond_to do |format| - if @question.save - format.html { redirect_to admin_phase_dmptemplate_path(:id => @question.section.version.phase_id, :version_id => @question.section.version_id, :section_id => @question.section_id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #update a question of a template - def admin_updatequestion - @question = Question.find(params[:id]) - authorize @question.section.version.phase.dmptemplate - @question.guidance = params["question-guidance-#{params[:id]}"] - @question.default_value = params["question-default-value-#{params[:id]}"] - @section = @question.section - @version = @section.version - @phase = @version.phase - respond_to do |format| - if @question.update_attributes(params[:question]) - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #delete a version, sections and questions - def admin_destroyquestion - @question = Question.find(params[:question_id]) - authorize @question.section.version.phase.dmptemplate - @section = @question.section - @version = @section.version - @phase = @version.phase - @question.destroy - respond_to do |format| - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - - - #SUGGESTED ANSWERS - #create suggested answers - def admin_createsuggestedanswer - @suggested_answer = SuggestedAnswer.new(params[:suggested_answer]) - authorize @suggested_answer.question.section.version.phase.dmptemplate - respond_to do |format| - if @suggested_answer.save - format.html { redirect_to admin_phase_dmptemplate_path(:id => @suggested_answer.question.section.version.phase_id, :version_id => @suggested_answer.question.section.version_id, :section_id => @suggested_answer.question.section_id, :question_id => @suggested_answer.question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - - #update a suggested answer of a template - def admin_updatesuggestedanswer - @suggested_answer = SuggestedAnswer.find(params[:id]) - authorize @suggested_answer.question.section.version.phase.dmptemplate - @question = @suggested_answer.question - @section = @question.section - @version = @section.version - @phase = @version.phase - - respond_to do |format| - if @suggested_answer.update_attributes(params[:suggested_answer]) - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #delete a suggested answer - def admin_destroysuggestedanswer - @suggested_answer = SuggestedAnswer.find(params[:suggested_answer]) - authorize @suggested_answer.question.section.version.phase.dmptemplate - @question = @suggested_answer.question - @section = @question.section - @version = @section.version - @phase = @version.phase - @suggested_answer.destroy - respond_to do |format| - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - -# GUIDANCES - - #create a guidance - def admin_createguidance - @question = Question.find(params[:question][:id]) - authorize @question.section.version.phase.dmptemplate - @guidance = Guidance.new(params[:guidance]) - @guidance.question_id = @question.id - #@question.guidance = params["new-question-guidance"] - #@question.default_value = params["new-question-default-value"] - respond_to do |format| - if @guidance.save - format.html { redirect_to admin_phase_dmptemplate_path(:id => @question.section.version.phase_id, :version_id => @question.section.version_id, :section_id => @question.section_id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #update a guidance of a template - def admin_updateguidance - @question = Question.find(params[:id]) - authorize @question.section.version.phase.dmptemplate - @question.guidance = params["question-guidance-#{params[:id]}"] - @question.default_value = params["question-default-value-#{params[:id]}"] - @section = @question.section - @version = @section.version - @phase = @version.phase - respond_to do |format| - if @question.update_attributes(params[:question]) - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') } - else - format.html { render action: "admin_phase" } - end - end - end - - #delete a version, sections and guidance - def admin_destroyguidance - @question = Question.find(params[:question_id]) - authorize @question.section.version.phase.dmptemplate - @section = @question.section - @version = @section.version - @phase = @version.phase - @question.destroy - respond_to do |format| - format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.destroyed_message') } - end - end - - -end \ No newline at end of file diff --git a/app/controllers/guidance_groups_controller.rb b/app/controllers/guidance_groups_controller.rb index 8b3a6d5..ce09688 100644 --- a/app/controllers/guidance_groups_controller.rb +++ b/app/controllers/guidance_groups_controller.rb @@ -1,24 +1,19 @@ class GuidanceGroupsController < ApplicationController after_action :verify_authorized + respond_to :html # GET /guidance_groups/1 def admin_show @guidance_group = GuidanceGroup.find(params[:id]) authorize @guidance_group - respond_to do |format| - format.html - end end - # GET add new guidance groups - def admin_new + # GET add new guidance groups + def admin_new @guidance_group = GuidanceGroup.new authorize @guidance_group - respond_to do |format| - format.html # new.html.erb - end - end + end # POST /guidance_groups @@ -26,56 +21,54 @@ def admin_create @guidance_group = GuidanceGroup.new(params[:guidance_group]) authorize @guidance_group - @guidance_group.organisation_id = current_user.organisation_id - if params[:save_publish] - @guidance_group.published = true - end + @guidance_group.org_id = current_user.org_id + if params[:save_publish] + @guidance_group.published = true + end - respond_to do |format| - if @guidance_group.save - format.html { redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.created_message') } - else - format.html { render action: "new" } - end + if @guidance_group.save + redirect_to admin_index_guidance_path, notice: _('Guidance group was successfully created.') + else + flash[:notice] = failed_create_error(@guidance_group, _('guidance group')) + render 'admin_new' end end # GET /guidance_groups/1/edit def admin_edit - @guidance_group = GuidanceGroup.find(params[:id]) - authorize @guidance_group + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group end # PUT /guidance_groups/1 def admin_update - @guidance_group = GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) authorize @guidance_group - @guidance_group.organisation_id = current_user.organisation_id - respond_to do |format| - if @guidance_group.update_attributes(params[:guidance_group]) - format.html { redirect_to admin_index_guidance_path(params[:guidance_group]), notice: I18n.t('org_admin.guidance_group.updated_message') } - else - format.html { render action: "edit" } - end + @guidance_group.org_id = current_user.org_id + @guidance_group.published = true unless params[:save_publish].nil? + + if @guidance_group.update_attributes(params[:guidance_group]) + redirect_to admin_index_guidance_path(params[:guidance_group]), notice: _('Guidance group was successfully updated.') + else + flash[:notice] = failed_update_error(@guidance_group, _('guidance group')) + render 'admin_edit' end end - +# TODO: This does not have a route in config/routes.rb and is unreachable! # PUT /guidance_groups/1 def admin_update_publish - @guidance_group = GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) authorize @guidance_group - @guidance_group.organisation_id = current_user.organisation_id - @guidance_group.published = true + @guidance_group.org.id = current_user.org.id + @guidance_group.published = true - respond_to do |format| - if @guidance_group.update_attributes(params[:guidance_group]) - format.html { redirect_to admin_index_guidance_path(params[:guidance_group]), notice: I18n.t('org_admin.guidance_group.updated_message') } - else - format.html { render action: "edit" } - end + if @guidance_group.update_attributes(params[:guidance_group]) + redirect_to admin_index_guidance_path(params[:guidance_group]), notice: _('Guidance group was successfully updated.') + else + redirect_to admin_index_guidance_path(@guidance_group), notice: failed_update_error(@guidance_group, _('guidance group')) end end @@ -83,12 +76,13 @@ # DELETE /guidance_groups/1 # DELETE /guidance_groups/1.json def admin_destroy - @guidance_group = GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) authorize @guidance_group - @guidance_group.destroy - respond_to do |format| - format.html { redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.destroyed_message') } + if @guidance_group.destroy + redirect_to admin_index_guidance_path, notice: _('Guidance group was successfully deleted.') + else + redirect_to admin_index_guidance_path, notice: failed_destroy_error(@guidance_group, _('guidance group')) end - end + end end \ No newline at end of file diff --git a/app/controllers/guidances_controller.rb b/app/controllers/guidances_controller.rb index 8df36eb..2356ef0 100644 --- a/app/controllers/guidances_controller.rb +++ b/app/controllers/guidances_controller.rb @@ -1,190 +1,102 @@ class GuidancesController < ApplicationController after_action :verify_authorized - + respond_to :html + + ## # GET /guidances def admin_index authorize Guidance @guidances = policy_scope(Guidance) - @guidance_groups = GuidanceGroup.where('organisation_id = ?', current_user.organisation_id ) - respond_to do |format| - format.html # index.html.erb - end + @guidance_groups = GuidanceGroup.where(org_id: current_user.org_id) end + ## # GET /guidances/1 def admin_show - @guidance = Guidance.find(params[:id]) + @guidance = Guidance.eager_load(:guidance_group, :themes).find(params[:id]) authorize @guidance - respond_to do |format| - format.html # show.html.erb - end end def admin_new @guidance = Guidance.new authorize @guidance - @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id) - @phases = nil - @dmptemplates.each do |template| - if @phases.nil? then - @phases = template.phases.all.order('number') - else - @phases = @phases + template.phases.all.order('number') - end - end - @versions = nil - @phases.each do |phase| - if @versions.nil? then - @versions = phase.versions.all.order('title') - else - @versions = @versions + phase.versions.all.order('title') - end - end - @sections = nil - @versions.each do |version| - if @sections.nil? then - @sections = version.sections.all.order('number') - else - @sections = @sections + version.sections.all.order('number') - end - end - @questions = nil - @sections.each do |section| - if @questions.nil? then - @questions = section.questions.all.order('number') - else - @questions = @questions + section.questions.all.order('number') - end - end - respond_to do |format| - format.html - end + @themes = Theme.all.order('title') + @guidance_groups = GuidanceGroup.where(org_id: current_user.org_id).order('name ASC') end - #setup variables for use in the dynamic updating - def update_phases - authorize Guidance - # updates phases, versions, sections and questions based on template selected - dmptemplate = Dmptemplate.find(params[:dmptemplate_id]) - # map to title and id for use in our options_for_select - @phases = dmptemplate.phases.map{|a| [a.title, a.id]}.insert(0, I18n.t('helpers.select_phase')) - @versions = dmptemplate.versions.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_version')) - @sections = dmptemplate.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = dmptemplate.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) - end - - def update_versions - authorize Guidance - # updates versions, sections and questions based on phase selected - phase = Phase.find(params[:phase_id]) - # map to name and id for use in our options_for_select - @versions = phase.versions.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_version')) - @sections = phase.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = phase.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) - end - - def update_sections - authorize Guidance - # updates sections and questions based on version selected - version = Version.find(params[:version_id]) - # map to name and id for use in our options_for_select - @sections = version.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = version.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) - end - - def update_questions - authorize Guidance - # updates songs based on artist selected - section = Section.find(params[:section_id]) - @questions = section.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) - end - - + ## # GET /guidances/1/edit def admin_edit - @guidance = Guidance.find(params[:id]) + @guidance = Guidance.eager_load(:themes, :guidance_group).find(params[:id]) authorize @guidance - @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id) - @phases = nil - @dmptemplates.each do |template| - if @phases.nil? then - @phases = template.phases.all.order('number') - else - @phases = @phases + template.phases.all.order('number') - end - end - @versions = nil - @phases.each do |phase| - if @versions.nil? then - @versions = phase.versions.all.order('title') - else - @versions = @versions + phase.versions.all.order('title') - end - end - @sections = nil - @versions.each do |version| - if @sections.nil? then - @sections = version.sections.all.order('number') - else - @sections = @sections + version.sections.all.order('number') - end - end - @questions = nil - @sections.each do |section| - if @questions.nil? then - @questions = section.questions.all.order('number') - else - @questions = @questions + section.questions.all.order('number') - end - end + @themes = Theme.all.order('title') + @guidance_groups = GuidanceGroup.where(org_id: current_user.org_id).order('name ASC') end + ## # POST /guidances def admin_create - @guidance = Guidance.new(params[:guidance]) + @guidance = Guidance.new(guidance_params) authorize @guidance @guidance.text = params["guidance-text"] - @guidance.question_id = params["question_id"] - if @guidance.published == true then - @gg = GuidanceGroup.find(@guidance.guidance_group_ids).first - if @gg.published == false || @gg.published.nil? then - @gg.published = true - @gg.save - end + + @guidance.themes = [] + if !guidance_params[:theme_ids].nil? + guidance_params[:theme_ids].map{|t| @guidance.themes << Theme.find(t.to_i) unless t.empty? } + end + + if @guidance.published == true then + @gg = GuidanceGroup.find(@guidance.guidance_group_id) + if @gg.published == false || @gg.published.nil? then + @gg.published = true + @gg.save end - respond_to do |format| - if @guidance.save - format.html { redirect_to admin_show_guidance_path(@guidance), notice: I18n.t('org_admin.guidance.created_message') } - else - format.html { render action: "new" } - end + end + + if @guidance.save + redirect_to admin_show_guidance_path(@guidance), notice: _('Guidance was successfully created.') + else + flash[:notice] = failed_create_error(@guidance, _('guidance')) + @themes = Theme.all.order('title') + @guidance_groups = GuidanceGroup.where(org_id: current_user.org_id).order('name ASC') + render action: "admin_new" end end + ## # PUT /guidances/1 def admin_update @guidance = Guidance.find(params[:id]) authorize @guidance @guidance.text = params["guidance-text"] - @guidance.question_id = params["question_id"] - respond_to do |format| - if @guidance.update_attributes(params[:guidance]) - format.html { redirect_to admin_show_guidance_path(params[:guidance]), notice: I18n.t('org_admin.guidance.updated_message') } - else - format.html { render action: "edit" } - end + + if @guidance.save(guidance_params) + redirect_to admin_show_guidance_path(params[:guidance]), notice: _('Guidance was successfully updated.') + else + flash[:notice] = failed_update_error(@guidance, _('guidance')) + @themes = Theme.all.order('title') + @guidance_groups = GuidanceGroup.where(org_id: current_user.org_id).order('name ASC') + + render action: "admin_edit" end end - + ## # DELETE /guidances/1 def admin_destroy @guidance = Guidance.find(params[:id]) authorize @guidance - @guidance.destroy - respond_to do |format| - format.html { redirect_to admin_index_guidance_path } + if @guidance.destroy + redirect_to admin_index_guidance_path, notice: _('Guidance was successfully deleted.') + else + redirect_to admin_index_guidance_path, notice: failed_destroy_error(@guidance, _('guidance')) end end + + private + def guidance_params + # The form on the page is weird. The text and template/section/question stuff is outside of the normal form params + params.require(:guidance).permit(:guidance_group_id, :published, theme_ids: []) + end end \ No newline at end of file diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index fe5a071..7a75e3c 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,12 +1,22 @@ class HomeController < ApplicationController + respond_to :html + ## + # Index + # + # Currently redirects user to their list of projects + # UNLESS + # User's contact name is not filled in + # Is this the desired behavior? def index if user_signed_in? name = current_user.name(false) +# TODO: Investigate if this is even relevant anymore. The name var will never be blank here because the logic in +# User says to return the email if the firstname and surname are empty regardless of the flag passed in if name.blank? redirect_to edit_user_registration_path else - redirect_to projects_url + redirect_to plans_url end end end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb new file mode 100644 index 0000000..474281a --- /dev/null +++ b/app/controllers/notes_controller.rb @@ -0,0 +1,82 @@ +class NotesController < ApplicationController + after_action :verify_authorized + respond_to :html + + require "pp" + + def create + @note = Note.new + user_id = params[:new_note][:user_id] + @note.user_id = user_id + answer_id = params[:new_note][:answer_id] + question_id = params[:new_note][:question_id] + plan_id = params[:new_note][:plan_id] + + # create answer if we dont already have one + if answer_id.present? + answer = Answer.find(answer_id) + else + answer = Answer.new + answer.plan_id = plan_id + answer.question_id = question_id + answer.user_id = user_id + answer.save! + end + + @note.answer= answer + @note.text = params["#{question_id}new_note_text"] + + authorize @note + + @plan = answer.plan + @answer = answer + @question = Question.find(question_id) + + if @note.save + @status = true + @notice = _('Comment was successfully created.') + else + @status = false + @notice = failed_create_error(@note, _('note')) + end + notes = answer.notes.all + @num_notes = notes.count + end + + + + def update + @note = Note.find(params[:note][:id]) + authorize @note + @note.text = params["#{params[:note][:id]}_note_text"] + + @answer = @note.answer + @question = @answer.question + @plan = @answer.plan + + if @note.update_attributes(params[:note]) + @notice = _('Comment was successfully saved.') + else + @notice = failed_update_error(@note, _('note')) + end + end + + + + def archive + @note = Note.find(params[:note][:id]) + authorize @note + @note.archived = true + @note.archived_by = params[:note][:archived_by] + + @answer = @note.answer + @question = @answer.question + @plan = @answer.plan + + if @note.update_attributes(params[:note]) + @notice = _('Comment removed.') + else + @notice = failed_destroy_error(@note, _('note')) + end + end +end diff --git a/app/controllers/organisation_users_controller.rb b/app/controllers/organisation_users_controller.rb deleted file mode 100644 index 6bdeeb3..0000000 --- a/app/controllers/organisation_users_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -class OrganisationUsersController < ApplicationController - - def admin_index - if user_signed_in? && current_user.is_org_admin? then - # find excluded user_id's - excluded_ids = params[:user_ids] - excluded_ids.each do |user_id| - User.find(user_id).remove_token - end - # remove their api_tokens - # find included user id's - params[:user_ids].each do |user_id| - User.find(user_id).keep_or_generate_token - end - # keep_or_generate_token - respond_to do |format| - format.html # index.html.erb - format.json { render json: @organisation_users } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - -end \ No newline at end of file diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb deleted file mode 100644 index cd4c340..0000000 --- a/app/controllers/organisations_controller.rb +++ /dev/null @@ -1,91 +0,0 @@ -class OrganisationsController < ApplicationController - after_action :verify_authorized - - # GET /organisations/1 - def admin_show - @organisation = Organisation.find(params[:id]) - authorize @organisation - respond_to do |format| - format.html # show.html.erb - end - end - - # GET /organisations/1/edit - def admin_edit - @organisation = Organisation.find(params[:id]) - authorize @organisation - - @languages = Language.all.order("name") - end - - - # PUT /organisations/1 - def admin_update - @organisation = Organisation.find(params[:id]) - authorize @organisation - @organisation.banner_text = params["org_banner_text"] - @organisation.logo = params[:organisation][:logo] if params[:organisation][:logo] - assign_params = params[:organisation].dup - assign_params.delete(:logo) - assign_params.delete(:contact_email) unless params[:organisation][:contact_email].present? - - respond_to do |format| - begin - if @organisation.update_attributes(assign_params) - format.html { redirect_to admin_show_organisation_path(params[:id]), notice: I18n.t("admin.org_updated_message") } - else - flash[:noice] = @organisation.errors.collect{|e| e.message}.join('
').html_safe - format.html { render action: "admin_edit" } - end - - rescue Dragonfly::Job::Fetch::NotFound => dflye - flash[:notice] = I18n.t("admin.org_bad_logo") - format.html {render action: "admin_edit"} - end - end - end - - #TODO: see if this is used by the ajax... otherwise lock it down - def parent - @organisation = Organisation.find(params[:id]) - authorize @organisation - parent_org = @organisation.find_by {|o| o.parent_id } - return parent_org - end - - #TODO: see is this is used by the ajax... otherwise lock it down - def children - @organisation = Organisation.find(params[:id]) - authorize @organisation - #if user_signed_in? then - children = {} - @organisation.children.each do |child| - children[child.id] = child.name - end - respond_to do |format| - format.json { render json: children.to_json } - end -# else -# render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) -# end - end - - #TODO: see if this is used by the ajax... otherwise lock it down - def templates - @organisation = Organisation.find(params[:id]) - authorize @organisation - #if user_signed_in? then - templates = {} - @organisation.dmptemplates.each do |template| - if template.is_published? then - templates[template.id] = template.title - end - end - respond_to do |format| - format.json { render json: templates.to_json } - end -# else -# render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) -# end - end -end diff --git a/app/controllers/orgs_controller.rb b/app/controllers/orgs_controller.rb new file mode 100644 index 0000000..a8f9835 --- /dev/null +++ b/app/controllers/orgs_controller.rb @@ -0,0 +1,52 @@ +class OrgsController < ApplicationController + after_action :verify_authorized + respond_to :html + + ## + # GET /organisations/1 + def admin_show + @org = Org.find(params[:id]) + authorize @org + end + + ## + # GET /organisations/1/edit + def admin_edit + @org = Org.find(params[:id]) + authorize @org + @languages = Language.all.order("name") + end + + ## + # PUT /organisations/1 + def admin_update + attrs = org_params + @org = Org.find(params[:id]) + authorize @org + @org.banner_text = params["org_banner_text"] + @org.logo = org_params[:logo] if org_params[:logo] + + begin + if @org.update_attributes(org_params) + redirect_to admin_show_org_path(params[:id]), notice: _('Organisation was successfully updated.') + else + # For some reason our custom validator returns as a string and not a hash like normal activerecord + # errors. We followed the example provided in the Rails guides when building the validator so + # its unclear why its doing this. Placing a check here for the data type. We should reasses though + # when doing a broader eval of the look/feel of the site and we come up with a standardized way of + # displaying errors + flash[:notice] = failed_update_error(@org, _('organisation')) + render action: "admin_edit" + end + rescue Dragonfly::Job::Fetch::NotFound => dflye + flash[:notice] = _('There seems to be a problem with your logo. Please upload it again.') + render action: "admin_edit" + end + end + + private + def org_params + params.require(:org).permit(:name, :abbreviation, :target_url, :is_other, :banner_text, :language_id, + :region_id, :logo, :contact_email) + end +end diff --git a/app/controllers/phases_controller.rb b/app/controllers/phases_controller.rb new file mode 100644 index 0000000..4abba8b --- /dev/null +++ b/app/controllers/phases_controller.rb @@ -0,0 +1,225 @@ +class PhasesController < ApplicationController + require 'pp' + + after_action :verify_authorized + + + # GET /plans/:plan_id/phases/:id/edit + def edit + + @plan = Plan.eager_load2(params[:plan_id]) + # authorization done on plan so found in plan_policy + authorize @plan + + phase_id = params[:id].to_i + @phase = @plan.template.phases.select {|p| p.id == phase_id}.first + @readonly = !@plan.editable_by?(current_user.id) + + # Now we need to get all the themed guidance for the plan. + # TODO: think this through again, there may be a better way to do this. + # + # Ultimately we are heading to a map from question id to theme to guidance. + # + # get the ids of the dynamically selected guidance groups + # and keep a map of them so we can extract the names later + guidance_groups_ids = @plan.guidance_groups.map{|pgg| pgg.id} + guidance_groups = GuidanceGroup.includes({guidances: :themes}).find(guidance_groups_ids) + + # create a map from theme to array of guidances + # where guidance is a hash with the text and the org name + theme_guidance = {} + + guidance_groups.each do |guidance_group| + guidance_group.guidances.each do |guidance| + guidance.themes.each do |theme| + title = theme.title + if !theme_guidance.has_key?(title) + theme_guidance[title] = Array.new + end + theme_guidance[title] << { + text: guidance.text, + org: guidance_group.name + ':' + } + end + end + end + + # create hash from question id to theme to guidance array + # so when we arerendering a question we can grab the guidance out of this + # + # question_guidance = { + # question.id => { + # theme => [ {text: "......", org: "....."} ] + # } + # } + @question_guidance = {} + @plan.questions.each do |question| + qg = {} + question.themes.each do |t| + title = t.title + qg[title] = theme_guidance[title] if theme_guidance.has_key?(title) + end + if !@question_guidance.has_key?(question.id) + @question_guidance[question.id] = Array.new + end + @question_guidance[question.id] = qg + end + + if !user_signed_in? then + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + + end + + + # GET /plans/PLANID/phases/PHASEID/status.json + def status + @plan = Plan.eager_load(params[:plan_id]) + authorize @plan + if user_signed_in? && @plan.readable_by?(current_user.id) then + respond_to do |format| + format.json { render json: @plan.status } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + + + #show and edit a phase of the template + def admin_show + @phase = Phase.eager_load(:sections).find_by('phases.id = ?', params[:id]) + authorize @phase + + @current = Template.current(@phase.template.dmptemplate_id) + @edit = (@phase.template.org == current_user.org) && (@phase.template == @current) + #@edit = params[:edit] == "true" ? true : false + + #verify if there are any sections if not create one + @sections = @phase.sections + if !@sections.any?() || @sections.count == 0 + @section = @phase.sections.build + @section.phase = @phase + @section.title = '' + @section.number = 1 + @section.published = true + @section.modifiable = true + @section.save + @new_sec = true + end + #verify if section_id has been passed, if so then open that section + if params.has_key?(:section_id) + @open = true + @section_id = params[:section_id].to_i + end + if params.has_key?(:question_id) + @question_id = params[:question_id].to_i + end + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + end + + + #preview a phase + def admin_preview + @phase = Phase.find(params[:id]) + authorize @phase + @template = @phase.template + end + + + #add a new phase to a passed template + def admin_add + @template = Template.find(params[:id]) + @phase = Phase.new + @phase.template = @template + authorize @phase + @phase.number = @template.phases.count + 1 + end + + + #create a phase + def admin_create + @phase = Phase.new(params[:phase]) + authorize @phase + + @phase.description = params["phase-desc"] + @phase.modifiable = true + if @phase.save + @phase.template.dirty = true + @phase.template.save! + + redirect_to admin_show_phase_path(id: @phase.id, edit: 'true'), notice: _('Information was successfully created.') + else + flash[:notice] = failed_create_error(@phase, _('phase')) + @template = @phase.template + render "admin_add" + end + end + + + #update a phase of a template + def admin_update + @phase = Phase.find(params[:id]) + authorize @phase + @phase.description = params["phase-desc"] + if @phase.update_attributes(params[:phase]) + @phase.template.dirty = true + @phase.template.save! + + redirect_to admin_show_phase_path(@phase), notice: _('Information was successfully updated.') + else + @sections = @phase.sections + @template = @phase.template + # These params may not be available in this context so they may need + # to be set to true without the check + @edit = true + @open = !params[:section_id].nil? + @section_id = (params[:section_id].nil? ? nil : params[:section_id].to_i) + @question_id = (params[:question_id].nil? ? nil : params[:question_id].to_i) + flash[:notice] = failed_update_error(@phase, _('phase')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render 'admin_show' + end + end + + #delete a phase + def admin_destroy + @phase = Phase.find(params[:phase_id]) + authorize @phase + @template = @phase.template + if @phase.destroy + @template.dirty = true + @template.save! + + redirect_to admin_template_template_path(@template), notice: _('Information was successfully deleted.') + else + @sections = @phase.sections + + # These params may not be available in this context so they may need + # to be set to true without the check + @edit = true + @open = !params[:section_id].nil? + @section_id = (params[:section_id].nil? ? nil : params[:section_id].to_i) + @question_id = (params[:question_id].nil? ? nil : params[:question_id].to_i) + flash[:notice] = failed_destroy_error(@phase, _('phase')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render 'admin_show' + end + end + +end diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index f5125d6..f967326 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -1,218 +1,503 @@ class PlansController < ApplicationController - #Uncomment the line below in order to add authentication to this page - users without permission will not be able to add new plans - #load_and_authorize_resource + require 'pp' + helper SettingsTemplateHelper + after_action :verify_authorized - - # GET /plans/1/edit - def edit - @plan = Plan.find(params[:id]) - authorize @plan - if !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@plan.readable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + def index + authorize Plan + @plans = current_user.plans + end - # PUT /plans/1 - # PUT /plans/1.json - def update - @plan = Plan.find(params[:id]) + + + # GET /plans/new + # ------------------------------------------------------------------------------------ + def new + @plan = Plan.new authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.update_attributes(params[:plan]) - format.html { redirect_to @plan, notice: I18n.t('helpers.project.success_update') } - format.json { head :no_content } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + + # Get all of the available funders and non-funder orgs + @funders = Org.funders.joins(:templates).where(templates: {published: true}).uniq.sort{|x,y| x.name <=> y.name } + @orgs = (Org.institutions + Org.managing_orgs).flatten.uniq.sort{|x,y| x.name <=> y.name } + + # Get the current user's org + @default_org = current_user.org if @orgs.include?(current_user.org) + + respond_to :html + end + + # POST /plans + # ------------------------------------------------------------------- + def create + @plan = Plan.new + authorize @plan + + @plan.principal_investigator = current_user.surname.blank? ? nil : "#{current_user.firstname} #{current_user.surname}" + @plan.data_contact = current_user.email + @plan.funder_name = plan_params[:funder_name] + + # If a template hasn't been identified look for the available templates + if plan_params[:template_id].blank? + template_options(plan_params[:org_id], plan_params[:funder_id]) + + # Return the 'Select a template' section + respond_to do |format| + format.js {} + end + + # Otherwise create the plan + else + @plan.template = Template.find(plan_params[:template_id]) + + if plan_params[:title].blank? + @plan.title = current_user.firstname.blank? ? _('My Plan') + '(' + @plan.template.title + ')' : + current_user.firstname + "'s" + _(" Plan") + else + @plan.title = plan_params[:title] + end + + if @plan.save + @plan.assign_creator(current_user) + + # pre-select org's guidance + ggs = GuidanceGroup.where(org_id: plan_params[:org_id], + optional_subset: false, + published: true) + if !ggs.blank? then @plan.guidance_groups << ggs end + + default = Template.find_by(is_default: true) + + msg = "#{_('Plan was successfully created.')} " + + if !default.nil? && default == @plan.template + # We used the generic/default template + msg += _('This plan is based on the default template.') + + elsif !@plan.template.customization_of.nil? + # We used a customized version of the the funder template + msg += "#{_('This plan is based on the')} #{plan_params[:funder_name]} #{_('template with customisations by the')} #{plan_params[:org_name]}" + + else + # We used the specified org's or funder's template + msg += "#{_('This plan is based on the')} #{@plan.template.org.name} template." + end + + flash[:notice] = msg + + respond_to do |format| + format.js { render js: "window.location='#{plan_url(@plan)}?editing=true'" } + end + + else + # Something went wrong so report the issue to the user + flash[:notice] = failed_create_error(@plan, 'Plan') + respond_to do |format| + format.js {} + end + end + end + end + + + + # GET /plans/show + def show + @plan = Plan.eager_load(params[:id]) + authorize @plan + @editing = (!params[:editing].nil? && @plan.administerable_by?(current_user.id)) + + # Get all Guidance Groups applicable for the plan and group them by org + @all_guidance_groups = @plan.get_guidance_group_options + @all_ggs_grouped_by_org = @all_guidance_groups.sort.group_by(&:org) + + # Important ones come first on the page - we grab the user's org's GGs and "Organisation" org type GGs + @important_ggs = [] + @important_ggs << [current_user.org, @all_ggs_grouped_by_org.delete(current_user.org)] + @all_ggs_grouped_by_org.each do |org, ggs| + if org.organisation? + @important_ggs << [org,ggs] + @all_ggs_grouped_by_org.delete(org) + end + end + + # Sort the rest by org name for the accordion + @all_ggs_grouped_by_org = @all_ggs_grouped_by_org.sort_by {|org,gg| org.name} + + @selected_guidance_groups = @plan.guidance_groups.pluck(:id) + @based_on = (@plan.template.customization_of.nil? ? @plan.template : Template.where(dmptemplate: @plan.template.customization_of).first) + + respond_to :html + end + + + + # we can go into this with the user able to edit or not able to edit + # the same edit form gets rendered but then different partials get used + # to render the answers depending on whether it is readonly or not + # + # we may or may not have a phase param. + # if we have none then we are editing/displaying the plan details + # if we have a phase then we are editing that phase. + # + # GET /plans/1/edit + def edit + @plan = Plan.find(params[:id]) + authorize @plan + # If there was no phase specified use the template's 1st phase + @phase = (params[:phase].nil? ? @plan.template.phases.first : Phase.find(params[:phase])) + @readonly = !@plan.editable_by?(current_user.id) + respond_to :html + end + + + # PUT /plans/1 + # PUT /plans/1.json + def update + @plan = Plan.find(params[:id]) + authorize @plan + + respond_to do |format| + if @plan.update_attributes(params[:plan]) + format.html { redirect_to @plan, :editing => false, notice: _('Plan was successfully updated.') } + format.json { head :no_content } + else + flash[:notice] = failed_update_error(@plan, _('plan')) + format.html { render action: "edit" } + end + end + end + + + + def update_guidance_choices + @plan = Plan.find(params[:id]) + authorize @plan + guidance_group_ids = params[:guidance_group_ids].blank? ? [] : params[:guidance_group_ids].map(&:to_i) + all_guidance_groups = @plan.get_guidance_group_options + plan_groups = @plan.guidance_groups + guidance_groups = GuidanceGroup.where( id: guidance_group_ids) + all_guidance_groups.each do |group| + # case where plan group exists but not in selection + if plan_groups.include?(group) && ! guidance_groups.include?(group) + # remove from plan groups + @plan.guidance_groups.delete(group) + end + # case where plan group dosent exist and in selection + if !plan_groups.include?(group) && guidance_groups.include?(group) + # add to plan groups + @plan.guidance_groups << group + end + end + @plan.save + flash[:notice] = _('Guidance choices saved.') + redirect_to action: "show" + end + + def share + @plan = Plan.find(params[:id]) + authorize @plan + #@plan_data = @plan.to_hash + end + + + def destroy + @plan = Plan.find(params[:id]) + authorize @plan + if @plan.destroy + respond_to do |format| + format.html { redirect_to plans_url, notice: _('Plan was successfully deleted.') } + end + else + respond_to do |format| + flash[:notice] = failed_create_error(@plan, _('plan')) + format.html { render action: "edit" } + end + end + end # GET /status/1.json - # only returns json, why is this here? + # only returns json, why is this here? def status - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.status } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def section_answers - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.section_answers(params[:section_id]) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def locked - @plan = Plan.find(params[:id]) - authorize @plan - if !@plan.nil? && user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.locked(params[:section_id],current_user.id) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def delete_recent_locks - @plan = Plan.find(params[:id]) + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.delete_recent_locks(current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + respond_to do |format| + format.json { render json: @plan.status } + end + end - def unlock_all_sections - @plan = Plan.find(params[:id]) + +# TODO: Remove these endpoints now that we're no longer using them +=begin + def section_answers + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.unlock_all_sections(current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + respond_to do |format| + format.json { render json: @plan.section_answers(params[:section_id]) } + end + end - def lock_section - @plan = Plan.find(params[:id]) + def locked + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.lock_section(params[:section_id], current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - format.json { render json: @plan.errors, status: :unprocessable_entity } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + if !@plan.nil? && user_signed_in? && @plan.readable_by(current_user.id) then + respond_to do |format| + format.json { render json: @plan.locked(params[:section_id],current_user.id) } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def unlock_section - @plan = Plan.find(params[:id]) + def delete_recent_locks + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.unlock_section(params[:section_id], current_user.id) - format.html { render action: "edit" } + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.delete_recent_locks(current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + def unlock_all_sections + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.unlock_all_sections(current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def answer - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.answer(params[:q_id], false).to_json(:include => :options) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + def lock_section + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.lock_section(params[:section_id], current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + format.json { render json: @plan.errors, status: :unprocessable_entity } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def warning - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.warning(params[:option_id]) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + def unlock_section + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.unlock_section(params[:section_id], current_user.id) + format.html { render action: "edit" } - def export - @plan = Plan.find(params[:id]) + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end +=end + + def answer + @plan = Plan.find(params[:id]) + authorize @plan + if !params[:q_id].nil? + respond_to do |format| + format.json { render json: @plan.answer(params[:q_id], false).to_json(:include => :options) } + end + else + respond_to do |format| + format.json { render json: {} } + end + end + end + + def show_export + @plan = Plan.find(params[:id]) + authorize @plan + render 'show_export' + end + + + + def export + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - @exported_plan = ExportedPlan.new.tap do |ep| - ep.plan = @plan - ep.user = current_user - #ep.format = request.format.try(:symbol) - ep.format = request.format.to_sym - plan_settings = @plan.settings(:export) + # If no format is specified, default to PDF + params[:format] = 'pdf' if params[:format].nil? - Settings::Dmptemplate::DEFAULT_SETTINGS.each do |key, value| - ep.settings(:export).send("#{key}=", plan_settings.send(key)) - end - end + @exported_plan = ExportedPlan.new.tap do |ep| + ep.plan = @plan + ep.phase_id = params[:phase_id] + ep.user = current_user + ep.format = params[:format].to_sym + plan_settings = @plan.settings(:export) - @exported_plan.save! # FIXME: handle invalid request types without erroring? - file_name = @exported_plan.project_name + Settings::Template::DEFAULT_SETTINGS.each do |key, value| + ep.settings(:export).send("#{key}=", plan_settings.send(key)) + end + end - respond_to do |format| - format.html - format.xml - format.json - format.csv { send_data @exported_plan.as_csv, filename: "#{file_name}.csv" } - format.text { send_data @exported_plan.as_txt, filename: "#{file_name}.txt" } - format.docx { headers["Content-Disposition"] = "attachment; filename=\"#{file_name}.docx\""} - format.pdf do - @formatting = @plan.settings(:export).formatting - render pdf: file_name, - margin: @formatting[:margin], - footer: { - center: t('helpers.plan.export.pdf.generated_by'), - font_size: 8, - spacing: (@formatting[:margin][:bottom] / 2) - 4, - right: '[page] of [topage]' - } - end - end - elsif !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@plan.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + begin + @exported_plan.save! + file_name = @exported_plan.settings(:export)[:value]['title'].gsub(/ /, "_") + + respond_to do |format| + format.html + format.csv { send_data @exported_plan.as_csv, filename: "#{file_name}.csv" } + format.text { send_data @exported_plan.as_txt, filename: "#{file_name}.txt" } + format.docx { render docx: 'export', filename: "#{file_name}.docx" } + format.pdf do + @formatting = @plan.settings(:export).formatting + render pdf: file_name, + margin: @formatting[:margin], + footer: { + center: _('This document was generated by %{application_name}') % {application_name: Rails.configuration.branding[:application][:name]}, + font_size: 8, + spacing: (@formatting[:margin][:bottom] / 2) - 4, + right: '[page] of [topage]' + } + end + end + rescue ActiveRecord::RecordInvalid => e + redirect_to show_export_plan_path(@plan), notice: _('%{format} is not a valid exporting format. Available formats to export are %{available_formats}.') % + {format: params[:format], available_formats: ExportedPlan::VALID_FORMATS.to_s} + end + end + + + + private + + def plan_params + params.require(:plan).permit(:org_id, :org_name, :funder_id, :funder_name, :template_id, :title) + end + + # different versions of the same template have the same dmptemplate_id + # but different version numbers so for each set of templates with the + # same dmptemplate_id choose the highest version number. + def get_most_recent( templates ) + groups = Hash.new + templates.each do |t| + k = t.dmptemplate_id + if !groups.has_key?(k) + groups[k] = t + else + other = groups[k] + if other.version < t.version + groups[k] = t + end + end + end + groups.values + end + + + def fixup_hash(plan) + rollup(plan, "notes", "answer_id", "answers") + rollup(plan, "answers", "question_id", "questions") + rollup(plan, "questions", "section_id", "sections") + rollup(plan, "sections", "phase_id", "phases") + + plan["template"]["phases"] = plan.delete("phases") + + ghash = {} + plan["guidance_groups"].map{|g| ghash[g["id"]] = g} + plan["plans_guidance_groups"].each do |pgg| + pgg["guidance_group"] = ghash[ pgg["guidance_group_id"] ] + end + + plan["template"]["org"] = Org.find(plan["template"]["org_id"]).serializable_hash() + end + + + # find all object under src_plan_key + # merge them into the items under obj_plan_key using + # super_id = id + # so we have answers which each have a question_id + # rollup(plan, "answers", "quesiton_id", "questions") + # will put the answers into the right questions. + def rollup(plan, src_plan_key, super_id, obj_plan_key) + id_to_obj = Hash.new() + plan[src_plan_key].each do |o| + id = o[super_id] + if !id_to_obj.has_key?(id) + id_to_obj[id] = Array.new + end + id_to_obj[id] << o + end + + plan[obj_plan_key].each do |o| + id = o["id"] + if id_to_obj.has_key?(id) + o[src_plan_key] = id_to_obj[ id ] + end + end + plan.delete(src_plan_key) + end + + # Collect all of the templates available for the org+funder combination + # -------------------------------------------------------------------------- + def template_options(org_id, funder_id) + @templates = [] + + if !org_id.blank? || !funder_id.blank? + if funder_id.blank? + # Load the org's template(s) + unless org_id.nil? + org = Org.find(org_id) + @templates = Template.valid.where(published: true, org: org, customization_of: nil).to_a + @msg = _("We found multiple DMP templates corresponding to the research organisation.") if @templates.count > 1 + end + + else + funder = Org.find(funder_id) + # Load the funder's template(s) + @templates = Template.valid.where(published: true, org: funder).to_a + + unless org_id.blank? + org = Org.find(org_id) + + # Swap out any organisational cusotmizations of a funder template + @templates.each do |tmplt| + customization = Template.valid.find_by(published: true, org: org, customization_of: tmplt.dmptemplate_id) + unless customization.nil? + @templates.delete(tmplt) + @templates << customization + end + end + end + + msg = _("We found multiple DMP templates corresponding to the funder.") if @templates.count > 1 + end + end + + # If no templates were available use the generic templates + if @templates.empty? + @msg = _("Using the generic Data Management Plan") + @templates << Template.find_by(is_default: true) + end + + @templates = @templates.sort{|x,y| x.title <=> y.title } if @templates.count > 1 + end + end diff --git a/app/controllers/project_groups_controller.rb b/app/controllers/project_groups_controller.rb deleted file mode 100644 index 2d81d39..0000000 --- a/app/controllers/project_groups_controller.rb +++ /dev/null @@ -1,94 +0,0 @@ -class ProjectGroupsController < ApplicationController - after_action :verify_authorized - - def create - @project_group = ProjectGroup.new(params[:project_group]) - authorize @project_group - access_level = params[:project_group][:access_level].to_i - if access_level >= 3 then - @project_group.project_administrator = true - end - if access_level >= 2 then - @project_group.project_editor = true - end - if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then - respond_to do |format| - if params[:project_group][:email].present? && params[:project_group][:email].length > 0 then - message = I18n.t('helpers.project.user_added') - if @project_group.save - if @project_group.user.nil? then - if User.find_by_email(params[:project_group][:email]).nil? then - User.invite!(:email => params[:project_group][:email]) - message = I18n.t('helpers.project.invitation_success') - @project_group.user = User.find_by_email(params[:project_group][:email]) - @project_group.save - else - @project_group.user = User.find_by_email(params[:project_group][:email]) - @project_group.save - UserMailer.sharing_notification(@project_group).deliver - end - else - UserMailer.sharing_notification(@project_group).deliver - end - flash[:notice] = message - format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug } - else - format.html { render action: "new" } - end - else - flash[:notice] = I18n.t('helpers.project.enter_email') - format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - - end - - def update - @project_group = ProjectGroup.find(params[:id]) - authorize @project_group - access_level = params[:project_group][:access_level].to_i - if access_level >= 3 then - @project_group.project_administrator = true - else - @project_group.project_administrator = false - end - if access_level >= 2 then - @project_group.project_editor = true - else - @project_group.project_editor = false - end - if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then - respond_to do |format| - if @project_group.update_attributes(params[:project_group]) - flash[:notice] = I18n.t('helpers.project.sharing_updated') - UserMailer.permissions_change_notification(@project_group).deliver - format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def destroy - @project_group = ProjectGroup.find(params[:id]) - authorize @project_group - if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then - user = @project_group.user - project = @project_group.project - @project_group.destroy - respond_to do |format| - flash[:notice] = I18n.t('helpers.project.access_removed') - UserMailer.project_access_removed_notification(user, project).deliver - format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end -end \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb deleted file mode 100644 index e5b9bed..0000000 --- a/app/controllers/projects_controller.rb +++ /dev/null @@ -1,357 +0,0 @@ -class ProjectsController < ApplicationController - before_filter :get_plan_list_columns, only: %i( index ) - after_action :verify_authorized - - # GET /projects - # GET /projects.json - def index - authorize Project - ## TODO: Is this A magic String? the "Show_shib_link?" as we define it and users dont see cookies - if user_signed_in? then - if (current_user.shibboleth_id.nil? || current_user.shibboleth_id.length == 0) && !cookies[:show_shib_link].nil? && cookies[:show_shib_link] == "show_shib_link" then - flash.notice = "Would you like to #{view_context.link_to I18n.t('helpers.shibboleth_to_link_text'), user_omniauth_shibboleth_path}".html_safe - end - - @projects = current_user.projects.filter(params[:filter]) - @has_projects = current_user.projects.any? # unfiltered count - - respond_to do |format| - format.html # index.html.erb - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end - - # GET /projects/1 - # GET /projects/1.json - def show - @project = Project.find(params[:id]) - authorize @project - @show_form = false - if params[:show_form] == "yes" then - @show_form = true - end - if user_signed_in? && @project.readable_by(current_user.id) then - respond_to do |format| - format.html # show.html.erb - end - elsif user_signed_in? then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end - - # GET /projects/new - # GET /projects/new.json - def new - if user_signed_in? then - @project = Project.new - authorize @project - @project.organisation = current_user.organisation - @funders = orgs_of_type(constant("organisation_types.funder"), true) - @templates = get_available_templates - @guidance_groups = get_available_guidance - @always_guidance = get_always_available_guidance - @institutions = orgs_of_type(constant("organisation_types.institution")) - - respond_to do |format| - format.html # new.html.erb - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end - - # GET /projects/1/edit - # Should this be removed? - def edit - @project = Project.find(params[:id]) - authorize @project - if !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@project.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end - - def share - @project = Project.find(params[:id]) - authorize @project - if !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@project.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end - - def export - @project = Project.find(params[:id]) - authorize @project - if !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - else - respond_to do |format| - format.html { render action: "export" } - - end - end - end - - # POST /projects - # POST /projects.json - def create - if user_signed_in? then - @project = Project.new(params[:project]) - authorize @project - if @project.dmptemplate.nil? && params[:project][:funder_id] != "" then # this shouldn't be necessary - see setter for funder_id in project.rb - funder = Organisation.find(params[:project][:funder_id]) - if funder.dmptemplates.count == 1 then - @project.dmptemplate = funder.published_templates.first - end - elsif @project.dmptemplate.nil? || params[:default_tag] == 'true' then - if @project.organisation.nil? || params[:default_tag] == 'true' || @project.organisation.published_templates.first.nil? then - @project.dmptemplate = Dmptemplate.find_by_is_default(true) - else - @project.dmptemplate = @project.organisation.published_templates.first - end - end - @project.principal_investigator = current_user.name(false) - - @project.title = I18n.t('helpers.project.my_project_name')+' ('+@project.dmptemplate.title+')' - @project.assign_creator(current_user.id) - respond_to do |format| - if @project.save - format.html { redirect_to({:action => "show", :id => @project.slug, :show_form => "yes"}, {:notice => I18n.t('helpers.project.success')}) } - else - format.html { render action: "new" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - # PUT /projects/1 - # PUT /projects/1.json - def update - @project = Project.find(params[:id]) - authorize @project - if user_signed_in? && @project.editable_by(current_user.id) then - if @project.update_attributes(params[:project]) - respond_to do |format| - format.html { redirect_to({:action => "show", :id => @project.slug, notice: I18n.t('helpers.project.success_update') }) } - end - else - respond_to do |format| - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - # DELETE /projects/1 - # DELETE /projects/1.json - def destroy - @project = Project.find(params[:id]) - authorize @project - if user_signed_in? && @project.editable_by(current_user.id) then - @project.destroy - - respond_to do |format| - format.html { redirect_to projects_url } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - # returns to AJAX call from frontend - # difficult to secure as it passes through params, and dosent curate data based - # on what the user can "view" or is public - # GET /projects/possible_templates.json - def possible_templates - if !params[:funder].nil? && params[:funder] != "" && params[:funder] != "undefined" then - funder = Organisation.find(params[:funder]) - else - funder = nil - end - if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then - institution = Organisation.find(params[:institution]) - else - institution = nil - end - templates = {} - unless funder.nil? then - funder.published_templates.each do |t| - templates[t.id] = t.title - end - end - if templates.count == 0 && !institution.nil? then - institution.published_templates.each do |t| - templates[t.id] = t.title - end - institution.children.each do |o| - o.published_templates.each do |t| - templates[t.id] = t.title - end - end - end - respond_to do |format| - format.json { render json: templates.to_json } - end - end - - # returns to AJAX call from frontend - # difficult to secure as it passes through params, and dosent curate data based - # on what the user can "view" or is public - def possible_guidance - authorize @project - if !params[:template].nil? && params[:template] != "" && params[:template] != "undefined" then - template = Dmptemplate.find(params[:template]) - else - template = nil - end - if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then - institution = Organisation.find(params[:institution]) - else - institution = nil - end - excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + orgs_of_type(constant("organisation_types.institution")) + Organisation.orgs_with_parent_of_type(constant("organisation_types.institution")) - guidance_groups = {} - ggs = GuidanceGroup.guidance_groups_excluding(excluded_orgs) - - ggs.each do |gg| - guidance_groups[gg.id] = gg.name - end - - #subset guidance that belong to the institution - unless institution.nil? then - authorize Project - optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id = ?", true, institution.id) - optional_gg.each do|optional| - guidance_groups[optional.id] = optional.name - end - - institution.children.each do |o| - o.guidance_groups.each do |gg| - include = false - gg.guidances.each do |g| - if g.dmptemplate.nil? || g.dmptemplate_id == template.id then - include = true - break - end - end - if include then - guidance_groups[gg.id] = gg.name - end - end - end - end - - #If template belongs to a funder and that funder has subset guidance display then. - if !template.nil? && template.organisation.organisation_type.name == constant("organisation_types.funder") then - optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id = ?", true, template.organisation_id) - optional_gg.each do|optional| - guidance_groups[optional.id] = optional.name - end - end - - - respond_to do |format| - format.json { render json: guidance_groups.to_json } - end - end - - private - def orgs_of_type(org_type_name, published_templates = false) - org_type = OrganisationType.find_by_name(org_type_name) - all_such_orgs = org_type.organisations - if published_templates then - with_published = Array.new - all_such_orgs.each do |o| - if o.published_templates.count > 0 then - with_published << o - end - end - return with_published.sort_by {|o| [o.sort_name, o.name] } - else - return all_such_orgs.sort_by {|o| [o.sort_name, o.name] } - end - end - - # ----------------------------------------------------------- - def get_available_templates - Dmptemplate.where(published: true) - end - - # ----------------------------------------------------------- - # Some guidance is always available to the user regardless of - # the template or institution. - # - # TODO: Reevaluate this. We should probably only do this for - # guidance groups who have guidance attached to themes - # ----------------------------------------------------------- - def get_always_available_guidance - # Exclude Funders, Institutions, or children of Institutions - excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + - orgs_of_type(constant("organisation_types.institution")) + - Organisation.orgs_with_parent_of_type(constant("organisation_types.institution")) - - GuidanceGroup.guidance_groups_excluding(excluded_orgs) - end - - # ----------------------------------------------------------- - # This is a simplified version of the old possible_guidance method - # above. It sends all possible guidance to the client instead of - # forcing the client to make ajax calls to change the available - # guidance list (that is now handled via JS clientside) - # - # TODO: Reevaluate whether or not this logic makes sense once the - # DB has been cleaned up - # ----------------------------------------------------------- - def get_available_guidance - guidance_groups = [] - - #subset guidance that belong to an institution - optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id IS NOT NULL", true) - optional_gg.each do|optional| - guidance_groups << optional.id - - optional.organisation.children.each do |o| - o.guidance_groups.each do |gg| - guidance_groups << gg.id - end - end - end - - # If template belongs to a funder and is an optional_subset - optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id IN (?)", true, orgs_of_type(constant("organisation_types.funder"))) - optional_gg.each do|optional| - guidance_groups << optional.id - end - - GuidanceGroup.where(id: guidance_groups) - end -end diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb new file mode 100644 index 0000000..dbc5613 --- /dev/null +++ b/app/controllers/questions_controller.rb @@ -0,0 +1,121 @@ +class QuestionsController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create a question + def admin_create + begin + @question = Question.new(question_params) + authorize @question + @question.modifiable = true + if @question.question_format.textfield? + @question.default_value = params["question-default-value-textfield"] + elsif @question.question_format.textarea? + @question.default_value = params["question-default-value-textarea"] + end + if @question.save + @question.section.phase.template.dirty = true + @question.section.phase.template.save! + if params[:example_answer].present? + example_answer = Annotation.new({question_id: @question.id, org_id: current_user.org_id, text: params[:example_answer], type: Annotation.types[:example_answer]}) + example_answer.save + end + if params[:guidance].present? + guidance = Annotation.new({question_id: @question.id, org_id: current_user.org_id, text: params[:guidance], type: Annotation.types[:guidance]}) + guidance.save + end + redirect_to admin_show_phase_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully created.') + else + @edit = (@question.section.phase.template.org == current_user.org) + @open = true + @phase = @question.section.phase + @section = @question.section + @sections = @phase.sections + @section_id = @question.section.id + @question_id = @question.id + + flash[:notice] = failed_create_error(@question, _('question')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render template: 'phases/admin_show' + end + rescue ActionController::ParameterMissing => e + flash[:notice] = e.message + end + end + + #update a question of a template + def admin_update + @question = Question.find(params[:id]) + authorize @question + guidance = @question.get_guidance_annotation(current_user.org_id) + if params["question-guidance-#{params[:id]}"].present? + if guidance.blank? + guidance = @question.annotations.build + guidance.type = :guidance + end + guidance.text = params["question-guidance-#{params[:id]}"] + guidance.save + end + if @question.question_format.textfield? + @question.default_value = params["question-default-value-textfield"] + elsif @question.question_format.textarea? + @question.default_value = params["question-default-value-textarea"] + end + @section = @question.section + @phase = @section.phase + template = @phase.template + if @question.update_attributes(params[:question]) + @phase.template.dirty = true + @phase.template.save! + + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully updated.') + else + @edit = (@phase.template.org == current_user.org) + @open = true + @sections = @phase.sections + @section_id = @section.id + @question_id = @question.id + + flash[:notice] = failed_update_error(@question, _('question')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render template: 'phases/admin_show' + end + end + + #delete question + def admin_destroy + @question = Question.find(params[:question_id]) + authorize @question + @section = @question.section + @phase = @section.phase + if @question.destroy + @phase.template.dirty = true + @phase.template.save! + + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: _('Information was successfully deleted.') + else + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: failed_destroy_error(@question, 'question') + end + end + + private + # Filters the valid attributes for a question according to each type. + # Note, that params[:question] and params[:question][:question_format_id] are required and their absence raises ActionController::ParameterMissing + def question_params + permitted = params.require(:question).except(:created_at, :updated_at).tap do |question_params| + question_params.require(:question_format_id) + q_format = QuestionFormat.find(question_params[:question_format_id]) + if !q_format.option_based? + question_params.delete(':question_options_attributes') + end + end + end +end \ No newline at end of file diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index ec550a3..a628929 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -3,45 +3,82 @@ def edit @languages = Language.all.order("name") + @orgs = Org.where(parent_id: nil).order("name") + @other_organisations = Org.where(parent_id: nil, is_other: true).pluck(:id) + @identifier_schemes = IdentifierScheme.where(active: true).order(:name) + @default_org = current_user.org + end + + # GET /resource + def new + oauth = {provider: nil, uid: nil} + IdentifierScheme.all.each do |scheme| + oauth = session["devise.#{scheme.name.downcase}_data"] unless session["devise.#{scheme.name.downcase}_data"].nil? + end + + @user = User.new + + unless oauth.nil? + # The OAuth provider could not be determined or there was no unique UID! + if oauth[:provider].nil? || oauth[:uid].nil? + flash[:notice] = t('identifier_schemes.new_login_failure') + + else + # Connect the new user with the identifier sent back by the OAuth provider + flash[:notice] = t('identifier_schemes.new_login_success') + UserIdentifier.create(identifier_scheme: oauth[:provider].upcase, + identifier: oauth[:uid], + user: @user) + end + end end # POST /resource def create - logger.debug "#{sign_up_params}" - if sign_up_params[:accept_terms] != "1" then - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.you_must_accept') - else - existing_user = User.find_by_email(sign_up_params[:email]) - if !existing_user.nil? then - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.email_already_registered') - else - build_resource(sign_up_params) - if resource.save - if resource.active_for_authentication? - set_flash_message :notice, :signed_up if is_navigational_format? - sign_up(resource_name, resource) - respond_with resource, :location => after_sign_up_path_for(resource) - else - set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format? - #expire_session_data_after_sign_in! <-- DEPRECATED BY DEVISE - respond_with resource, :location => after_inactive_sign_up_path_for(resource) - end - else - clean_up_passwords resource - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.error_registration_check') - end - end + #logger.debug "#{sign_up_params}" + if sign_up_params[:accept_terms] != "1" then + redirect_to after_sign_up_error_path_for(resource), alert: _('You must accept the terms and conditions to register.') + else + existing_user = User.find_by_email(sign_up_params[:email]) + if !existing_user.nil? # If email exists + if (existing_user.password == "" || existing_user.password.nil?) && existing_user.confirmed_at.nil? # If user has not accepted invitation yet + existing_user.destroy # Only solution for now + super + else + redirect_to after_sign_up_error_path_for(resource), alert: _('That email address is already registered.') + end + else + build_resource(sign_up_params) + if resource.save + if resource.active_for_authentication? + set_flash_message :notice, :signed_up if is_navigational_format? + sign_up(resource_name, resource) + UserMailer.welcome_notification(current_user).deliver + respond_with resource, location: after_sign_up_path_for(resource) + else + set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format? + #expire_session_data_after_sign_in! <-- DEPRECATED BY DEVISE + respond_with resource, location: after_inactive_sign_up_path_for(resource) + end + else + clean_up_passwords resource + redirect_to after_sign_up_error_path_for(resource), alert: _('Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long.') + end + end end end - def update - if user_signed_in? then - @user = User.find(current_user.id) - - do_update + def update + if user_signed_in? then + @orgs = Org.where(parent_id: nil).order("name") + @default_org = current_user.org + @other_organisations = Org.where(parent_id: nil, is_other: true).pluck(:id) + @identifier_schemes = IdentifierScheme.where(active: true).order(:name) + @languages = Language.sorted_by_abbreviation + do_update(require_password=needs_password?(current_user, params)) else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) end end @@ -51,61 +88,97 @@ # ie if password or email was changed # extend this as needed def needs_password?(user, params) - user.email != params[:user][:email] || - params[:user][:password].present? + user.email != params[:user][:email] || params[:user][:password].present? end def do_update(require_password = true, confirm = false) - if require_password then - successfully_updated = if needs_password?(@user, params) - @user.update_with_password(params[:user]) - else - # remove the virtual current_password attribute update_without_password - # doesn't know how to ignore it - params[:user].delete(:current_password) - @user.update_without_password(params[:user]) + mandatory_params = true + message = _('Save Unsuccessful.') + ' ' # added to by below, overwritten otherwise + # ensure that the required fields are present + if params[:user][:email].blank? + message +=_('Please enter an email address.') + ' ' + mandatory_params &&= false + end + if params[:user][:firstname].blank? + message +=_('Please enter a First name.') + ' ' + mandatory_params &&= false + end + if params[:user][:surname].blank? + message +=_('Please enter a Last name.') + ' ' + mandatory_params &&= false + end + if params[:user][:org_id].blank? + message += _('Please select an organisation, or select Other.') + mandatory_params &&= false + end + if mandatory_params # has the user entered all the details + if require_password # user is changing email or password + if current_user.email != params[:user][:email] # if user is changing email + if params[:user][:current_password].blank? # password needs to be present + message = _('Please enter your password to change email address.') + successfully_updated = false + else + successfully_updated = current_user.update_with_password(password_update) + end + elsif params[:user][:password].present? # if user is changing password + successfully_updated = false # shared across first 3 conditions + if params[:user][:current_password].blank? + message = _('Please enter your current password') + elsif params[:user][:password_confirmation].blank? + message = _('Please enter a password confirmation') + elsif params[:user][:password] != params[:user][:password_confirmation] + message = _('Password and comfirmation must match') + else + successfully_updated = current_user.update_with_password(password_update) + end + else # potentially unreachable... but I dont like to leave off the else + successfully_updated = current_user.update_with_password(password_update) + end + else # password not required + successfully_updated = current_user.update_without_password(update_params) end else - @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation]) - successfully_updated = @user.update_without_password(params[:user]) + successfully_updated = false end - # If the user selected a new language setting, go ahead and reset the locale - if params[:user][:language_id] - if @user.language_id != params[:user][:language_id] - params[:locale] = Language.find(params[:user][:language_id]).abbreviation - set_locale - end - end - #unlink shibboleth from user's details if params[:unlink_flag] == 'true' then - @user.update_attributes(:shibboleth_id => "") + current_user.update_attributes(shibboleth_id: "") end + #render the correct page if successfully_updated - if confirm then - @user.skip_confirmation! - @user.save! - end - set_flash_message :notice, :updated - # Sign in the user bypassing validation in case his password changed - sign_in @user, :bypass => true - - #if params[:unlink_flag] == 'true' then - redirect_to({:controller => "registrations", :action => "edit"}, {:notice => I18n.t('helpers.project.details_update_success')}) - #else - # redirect_to({:controller => "projects", :action => "index"}, {:notice => I18n.t('helpers.project.details_update_success')}) - #end + if confirm + current_user.skip_confirmation! # will error out if confirmable is turned off in user model + current_user.save! + end + session[:locale] = current_user.get_locale unless current_user.get_locale.nil? + set_gettext_locale #Method defined at controllers/application_controller.rb + set_flash_message :notice, _('Details successfully updated.') + sign_in current_user, bypass: true # Sign in the user bypassing validation in case his password changed + redirect_to edit_user_registration_path, notice: _('Details successfully updated.') else + flash[:notice] = message.blank? ? failed_update_error(current_user, _('profile')) : message render "edit" end end def sign_up_params - params.require(:user).permit(:email, :password, :password_confirmation, :accept_terms, - :organisation_id, :other_organisation) + params.require(:user).permit(:email, :password, :password_confirmation, :firstname, :surname, + :accept_terms, :org_id, :other_organisation) + end + + def update_params + params.require(:user).permit(:firstname, :org_id, :other_organisation, + :language_id, :surname) + end + + def password_update + params.require(:user).permit(:email, :firstname, :current_password, + :org_id, :language_id, :password, + :password_confirmation, :surname, + :other_organisation) end end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb new file mode 100644 index 0000000..3a50d54 --- /dev/null +++ b/app/controllers/roles_controller.rb @@ -0,0 +1,92 @@ +class RolesController < ApplicationController + respond_to :html + after_action :verify_authorized + + def create + registered = true + @role = Role.new(role_params) + authorize @role + access_level = params[:role][:access_level].to_i + set_access_level(access_level) + if params[:user].present? + if @role.plan.owner.present? && @role.plan.owner.email == params[:user] + flash[:notice] = _('Cannot share plan with %{email} since that email matches with the owner of the plan.') % {email: params[:user]} + else + if Role.find_by(plan: @role.plan, user: User.find_by(email: params[:user])) # role already exists + flash[:notice] = _('Plan is already shared with %{email}.') % {email: params[:user]} + else + message = _('Plan shared with %{email}.') % {email: params[:user]} + user = User.find_by(email: params[:user]) + if user.nil? + registered = false + User.invite!(email: params[:user]) + message = _('Invitation to %{email} issued successfully.') % {email: params[:user]} + user = User.find_by(email: params[:user]) + end + @role.user = user + if @role.save + if registered then UserMailer.sharing_notification(@role, current_user).deliver_now end + flash[:notice] = message + else + flash[:notice] = failed_create_error(@role, _('role')) + end + end + end + else + flash[:notice] = _('Please enter an email address') + end + redirect_to controller: 'plans', action: 'share', id: @role.plan.id + end + + + def update + @role = Role.find(params[:id]) + authorize @role + access_level = params[:role][:access_level].to_i + set_access_level(access_level) + if @role.update_attributes(role_params) + flash[:notice] = _('Sharing details successfully updated.') + UserMailer.permissions_change_notification(@role, current_user).deliver_now + redirect_to controller: 'plans', action: 'share', id: @role.plan.id + else + flash[:notice] = failed_create_error(@role, _('role')) + render action: "edit" + end + end + + def destroy + @role = Role.find(params[:id]) + authorize @role + user = @role.user + plan = @role.plan + @role.destroy + flash[:notice] = _('Access removed') + UserMailer.project_access_removed_notification(user, plan, current_user).deliver_now + redirect_to controller: 'plans', action: 'share', id: @role.plan.id + end + + private + + def role_params + params.require(:role).permit(:plan_id) + end + + def set_access_level(access_level) + if access_level >= 1 + @role.commenter = true + else + @role.commenter = false + end + if access_level >= 2 + @role.editor = true + else + @role.editor = false + end + if access_level >= 3 + @role.administrator = true + else + @role.administrator = false + end + end + +end diff --git a/app/controllers/sections_controller.rb b/app/controllers/sections_controller.rb new file mode 100644 index 0000000..b6ef3d1 --- /dev/null +++ b/app/controllers/sections_controller.rb @@ -0,0 +1,91 @@ +class SectionsController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create a section + def admin_create + @section = Section.new(params[:section]) + authorize @section + @section.description = params["section-desc"] + @section.modifiable = true + @phase = @section.phase + if @section.save + @section.phase.template.dirty = true + @section.phase.template.save! + + redirect_to admin_show_phase_path(id: @section.phase_id, + :section_id => @section.id, edit: 'true'), notice: _('Information was successfully created.') + else + @edit = (@phase.template.org == current_user.org) + @open = true + @sections = @phase.sections + @section_id = @section.id + @question_id = nil + flash[:notice] = failed_create_error(@section, _('section')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render template: 'phases/admin_show' + end + end + + + #update a section of a template + def admin_update + @section = Section.includes(phase: :template).find(params[:id]) + authorize @section + @section.description = params["section-desc-#{params[:id]}"] + @phase = @section.phase + if @section.update_attributes(params[:section]) + @section.phase.template.dirty = true + @section.phase.template.save! + + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id , edit: 'true'), notice: _('Information was successfully updated.') + else + @edit = (@phase.template.org == current_user.org) + @open = true + @sections = @phase.sections + @section_id = @section.id + @question_id = nil + flash[:notice] = failed_update_error(@section, _('section')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render template: 'phases/admin_show' + end + end + + + #delete a section and questions + def admin_destroy + @section = Section.includes(phase: :template).find(params[:section_id]) + authorize @section + @phase = @section.phase + + if @section.destroy + @phase.template.dirty = true + @phase.template.save! + + redirect_to admin_show_phase_path(id: @phase.id, edit: 'true' ), notice: _('Information was successfully deleted.') + else + @edit = (@phase.template.org == current_user.org) + @open = true + @sections = @phase.sections + @section_id = @section.id + @question_id = nil + + flash[:notice] = failed_destroy_error(@section, _('section')) + if @phase.template.customization_of.present? + @original_org = Template.where(dmptemplate_id: @phase.template.customization_of).first.org + else + @original_org = @phase.template.org + end + render template: 'phases/admin_show' + end + end + +end \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index aa0b716..a4154d9 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,15 +1,38 @@ class SessionsController < Devise::SessionsController - # Capture the user's shibboleth id if they're coming in from an IDP - def create + # POST /auth/:provider/callback + # --------------------------------------------------------------------- +=begin + def oauth_create existing_user = User.find_by_email(params[:user][:email]) - - if !existing_user.nil? && !params[:shibboleth_data].nil? then - #after authentication verify if session[:shibboleth] exists - existing_user.update_attributes(shibboleth_id: session[:shibboleth_data][:uid]) + + unless params[:omniauth].nil? + existing_user = UserIdentifier.find_by(identifier: params[:omniauth][:auth]) end - + end +=end + + # Capture the user's shibboleth id if they're coming in from an IDP + # --------------------------------------------------------------------- + def create + existing_user = User.find_by(email: params[:user][:email]) + if !existing_user.nil? + +# TODO: Not sure why we check for shib data in params and then use session value below. We should move this to the +# new user_identifiers table + if !params[:shibboleth_data].nil? + #after authentication verify if session[:shibboleth] exists + existing_user.update_attributes(shibboleth_id: session[:shibboleth_data][:uid]) + end + session[:locale] = existing_user.get_locale unless existing_user.get_locale.nil? + set_gettext_locale #Method defined at controllers/application_controller.rb + end super end + def destroy + super + session[:locale] = nil + set_gettext_locale #Method defined at controllers/application_controller.rb + end end \ No newline at end of file diff --git a/app/controllers/settings.rb b/app/controllers/settings.rb index 612db61..a0342b3 100644 --- a/app/controllers/settings.rb +++ b/app/controllers/settings.rb @@ -1,5 +1,4 @@ module Settings class SettingsController < ApplicationController - end end diff --git a/app/controllers/settings/plans_controller.rb b/app/controllers/settings/plans_controller.rb index 2c65aea..c406401 100644 --- a/app/controllers/settings/plans_controller.rb +++ b/app/controllers/settings/plans_controller.rb @@ -2,13 +2,15 @@ class PlansController < SettingsController before_filter :get_settings + after_action :verify_authorized def show - authorize @plan + authorize [:settings, @plan] respond_to do |format| format.html format.partial + format.json{ render json: settings_json } end end @@ -20,6 +22,7 @@ if params[:commit] == 'Reset' s.formatting = nil s.fields = nil + s.title = nil else s.formatting = export_params[:formatting] s.fields = export_params[:fields] @@ -28,13 +31,13 @@ end if settings.save - respond_to do |format| - format.html { redirect_to(export_project_path(@plan.project)) } - end + flash[:notice] = _('Export settings updated successfully.') else - settings.formatting = nil - @export_settings = settings - render(action: :show) + flash[:alert] = _('An error has occurred while saving/resetting your export settings.') + end + respond_to do |format| + format.html { redirect_to(show_export_plan_path(@plan.id)) } + # format.json { render json: settings_json } end end diff --git a/app/controllers/settings/projects_controller.rb b/app/controllers/settings/projects_controller.rb deleted file mode 100644 index 6ba2cd3..0000000 --- a/app/controllers/settings/projects_controller.rb +++ /dev/null @@ -1,46 +0,0 @@ -module Settings - class ProjectsController < SettingsController - - before_filter :get_plan_list_columns - before_filter :get_settings - - after_action :verify_authorized - - def show - authorize [:settings, Project] - respond_to do |format| - format.html - - format.json{ render json: settings_json } - end - end - - def update - authorize [:settings, Project] - columns = (params[:columns] || {}) - - if @settings.update_attributes(columns: columns) - respond_to do |format| - format.html { redirect_to(projects_path) } - - format.json{ render json: settings_json } - end - else - render(action: :show) # Expect #show to display errors etc - end - end - - private - - def get_settings - @settings = current_user.settings(:plan_list) - # :name column should always be present (displayed as a disabled checkbox) - # so it's not necessary to include it in the list here - @all_columns -= [:name] - end - - def settings_json - @settings_json ||= { selected_columns: @settings.columns, all_columns: @all_columns }.to_json - end - end -end diff --git a/app/controllers/splash_logs_controller.rb b/app/controllers/splash_logs_controller.rb index c2824d5..4fce98d 100644 --- a/app/controllers/splash_logs_controller.rb +++ b/app/controllers/splash_logs_controller.rb @@ -1,20 +1,19 @@ class SplashLogsController < ApplicationController + respond_to :html + ## # POST /answers - # POST /answers.json def create @splash_log = SplashLog.new() @splash_log.destination = params[:destination] - respond_to do |format| - if @splash_log.save - cookies[:dmp_splash_seen] = { - value: 'splash_dialog_seen', - expires: 3.hours.from_now, - } - format.html { redirect_to params[:destination] } - else - format.html { redirect_to home_url } - end + if @splash_log.save + cookies[:dmp_splash_seen] = { + value: 'splash_dialog_seen', + expires: 3.hours.from_now, + } + redirect_to params[:destination] + else + redirect_to home_url end end end \ No newline at end of file diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index 8408cfe..6f38009 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -2,7 +2,7 @@ def about_us dcc_news_feed_url = "http://www.dcc.ac.uk/news/dmponline-0/feed" - @dcc_news_feed = Feedjira::Feed.fetch_and_parse dcc_news_feed_url + @dcc_news_feed = Feedjira::Feed.fetch_and_parse dcc_news_feed_url respond_to do |format| format.rss { redirect_to dcc_news_feed_url } format.html @@ -11,8 +11,63 @@ def contact_us end - + def roadmap + end + def public_plans + @plans = Plan.publicly_visible + end + + # GET /plans/[:plan_slug]/public_export + # ------------------------------------------------------------- + def public_export + redirect_to public_plans_path, notice: _('Exporting public plan is under development. Apologies for any inconvience.') + #@plan = Plan.find(params[:id]) + + # Force PDF response + #request.format = :pdf + + # if the project is designated as public + #if @plan.visibility == :publicly_visible + # if !@plan.nil? + # @exported_plan = ExportedPlan.new.tap do |ep| + # ep.plan = @plan + # ep.user = current_user ||= nil + # #ep.format = request.format.try(:symbol) + # ep.format = request.format.to_sym + # plan_settings = @plan.settings(:export) + + # Settings::Dmptemplate::DEFAULT_SETTINGS.each do |key, value| + # ep.settings(:export).send("#{key}=", plan_settings.send(key)) + # end + # end + + # @exported_plan.save! # FIXME: handle invalid request types without erroring? + # file_name = @exported_plan.project_name + + # respond_to do |format| + # format.pdf do + # @formatting = @plan.settings(:export).formatting + # render pdf: file_name, + # margin: @formatting[:margin], + # footer: { + # center: t('helpers.plan.export.pdf.generated_by'), + # font_size: 8, + # spacing: (@formatting[:margin][:bottom] / 2) - 4, + # right: '[page] of [topage]' + # } + # end + # end + + # else + # the project has no plans for some reason + # redirect_to public_plans_path, notice: _('The plan is incomplete.') + # end + #else + # Otherwise redirect to the home page with an unauthorized message + # redirect_to public_plans_path, notice: _('This account does not have access to that plan.') + #end + end end \ No newline at end of file diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb new file mode 100644 index 0000000..742ce33 --- /dev/null +++ b/app/controllers/templates_controller.rb @@ -0,0 +1,326 @@ +# [+Project:+] DMPRoadmap +# [+Description:+] This controller is responsible for all the actions in the admin interface under templates (e.g. phases, versions, sections, questions, suggested answer) (index; show; create; edit; delete) +# [+Copyright:+] Digital Curation Centre and University of California Curation Center + +class TemplatesController < ApplicationController + respond_to :html + after_action :verify_authorized + + # GET /org/admin/templates/:id/admin_index + # ----------------------------------------------------- + def admin_index + authorize Template + + funder_templates, org_templates, customizations = [], [], [] + + # Get all of the unique template family ids (dmptemplate_id) for each funder and the current org + funder_ids = Org.funders.includes(:templates).collect{|f| f.templates.where(published: true).valid.collect{|ft| ft.dmptemplate_id } }.flatten.uniq + org_ids = current_user.org.templates.where(customization_of: nil).valid.collect{|t| t.dmptemplate_id }.flatten.uniq + + org_ids.each do |id| + current = Template.current(id) + live = Template.live(id) + org_templates << {current: current, live: live} + end + funder_ids.each do |id| + funder_live = Template.live(id) + current = Template.org_customizations(id, current_user.org_id) + # if we have a current template, check to see if there is a live version + live = current.nil? ? nil : Template.live(current.dmptemplate_id) + # need a current version, default to funder live if no custs exist + current = funder_live unless current.present? + + funder_templates << {current: current, live: live, funder_live: funder_live, stale: funder_live.updated_at > current.created_at} + end + + @funder_templates = funder_templates.sort{|x,y| + x[:current].title <=> y[:current].title + } + @org_templates = org_templates.sort{|x,y| + x[:current].title <=> y[:current].title + } + end + + # GET /org/admin/templates/:id/admin_customize + # ----------------------------------------------------- + def admin_customize + @template = Template.find(params[:id]) + authorize @template + + customisation = Template.deep_copy(@template) + customisation.org = current_user.org + customisation.version = 0 + customisation.customization_of = @template.dmptemplate_id + customisation.dmptemplate_id = loop do + random = rand 2147483647 + break random unless Template.exists?(dmptemplate_id: random) + end + customisation.save + + customisation.phases.includes(:sections, :questions).each do |phase| + phase.modifiable = false + phase.save! + phase.sections.each do |section| + section.modifiable = false + section.save! + section.questions.each do |question| + question.modifiable = false + question.save! + end + end + end + + redirect_to admin_template_template_path(customisation) + end + + # GET /org/admin/templates/:id/admin_transfer_customization + # the funder template's id is passed through here + # ----------------------------------------------------- + def admin_transfer_customization + @template = Template.includes(:org).find(params[:id]) + authorize @template + new_customization = Template.deep_copy(@template) + new_customization.org_id = current_user.org_id + new_customization.published = false + new_customization.customization_of = @template.dmptemplate_id + new_customization.dirty = true + new_customization.phases.includes(sections: :questions).each do |phase| + phase.modifiable = false + phase.save + phase.sections.each do |section| + section.modifiable = false + section.save + section.questions.each do |question| + question.modifiable = false + question.save + end + end + end + customizations = Template.includes(:org, phases:[sections: [questions: :annotations]]).where(org_id: current_user.org_id, customization_of: @template.dmptemplate_id).order(version: :desc) + # existing version to port over + max_version = customizations.first + new_customization.dmptemplate_id = max_version.dmptemplate_id + new_customization.version = max_version.version + 1 + # here we rip the customizations out of the old template + # First, we find any customzed phases or sections + max_version.phases.each do |phase| + # check if the phase was added as a customization + if phase.modifiable + # deep copy the phase and add it to the template + phase_copy = Phase.deep_copy(phase) + phase_copy.number = new_customization.phases.length + 1 + phase_copy.template_id = new_customization.id + phase_copy.save! + else + # iterate over the sections to see if any of them are customizations + phase.sections.each do |section| + if section.modifiable + # this is a custom section + section_copy = Section.deep_copy(section) + customization_phase = new_customization.phases.includes(:sections).where(number: phase.number).first + section_copy.phase_id = customization_phase.id + # custom sections get added to the end + section_copy.number = customization_phase.sections.length + 1 + # section from phase with corresponding number in the main_template + section_copy.save! + else + # not a customized section, iterate over questions + customization_phase = new_customization.phases.includes(sections: [questions: :annotations]).where(number: phase.number).first + customization_section = customization_phase.sections.where(number: section.number).first + section.questions.each do |question| + # find corresponding question in new template + customization_question = customization_section.questions.where(number: question.number).first + # apply annotations + question.annotations.each do |annotation| + annotation_copy = Annotation.deep_copy(annotation) + annotation_copy.question_id = customization_question.id + annotation_copy.save! + end + end + end + end + end + end + new_customization.save + redirect_to admin_template_template_path(new_customization) + end + + # PUT /org/admin/templates/:id/admin_publish + # ----------------------------------------------------- + def admin_publish + @template = Template.find(params[:id]) + authorize @template + + current = Template.current(@template.dmptemplate_id) + + # Only allow the current version to be updated + if current != @template + redirect_to admin_template_template_path(@template), notice: _('You can not publish a historical version of this template.') + + else + # Unpublish the older published version if there is one + live = Template.live(@template.dmptemplate_id) + if !live.nil? and self != live + live.published = false + live.save! + end + # Set the dirty flag to false + @template.dirty = false + @template.published = true + @template.save + + flash[:notice] = _('Your template has been published and is now available to users.') + + redirect_to admin_index_template_path(current_user.org) + end + end + + # PUT /org/admin/templates/:id/admin_unpublish + # ----------------------------------------------------- + def admin_unpublish + template = Template.find(params[:id]) + authorize template + + # Unpublish the live version + @template = Template.live(template.dmptemplate_id) + + if @template.nil? + flash[:notice] = _('That template is not currently published.') + else + @template.published = false + @template.save + flash[:notice] = _('Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it') + end + + redirect_to admin_index_template_path(current_user.org) + end + + # GET /org/admin/templates/:id/admin_template + # ----------------------------------------------------- + def admin_template + @template = Template.includes(:org, phases: [sections: [questions: [:question_options, :question_format, :annotations]]]).find(params[:id]) + authorize @template + + @current = Template.current(@template.dmptemplate_id) + + if @template == @current + # If the template is published + if @template.published? + # We need to create a new, editable version + new_version = Template.deep_copy(@template) + new_version.version = (@template.version + 1) + new_version.published = false + new_version.save + @template = new_version +# @current = Template.current(@template.dmptemplate_id) + end + else + flash[:notice] = _('You are viewing a historical version of this template. You will not be able to make changes.') + end + + # If the template is published + if @template.published? + # We need to create a new, editable version + new_version = Template.deep_copy(@template) + new_version.version = (@template.version + 1) + new_version.published = false + new_version.save + @template = new_version + end + + # once the correct template has been generated, we convert it to hash + @hash = @template.to_hash + end + + + # PUT /org/admin/templates/:id/admin_update + # ----------------------------------------------------- + def admin_update + @template = Template.find(params[:id]) + authorize @template + + current = Template.current(@template.dmptemplate_id) + + # Only allow the current version to be updated + if current != @template + redirect_to admin_template_template_path(@template), notice: _('You can not edit a historical version of this template.') + + else + if @template.description != params["template-desc"] || + @template.title != params[:template][:title] + @template.dirty = true + end + + @template.description = params["template-desc"] + if @template.update_attributes(params[:template]) + flash[:notice] = _('Information was successfully updated.') + + else + flash[:notice] = failed_update_error(@template, _('template')) + end + + @hash = @template.to_hash + render 'admin_template' + end + end + + + # GET /org/admin/templates/:id/admin_new + # ----------------------------------------------------- + def admin_new + authorize Template + end + + + # POST /org/admin/templates/:id/admin_create + # ----------------------------------------------------- + def admin_create + # creates a new template with version 0 and new dmptemplate_id + @template = Template.new(params[:template]) + authorize @template + @template.org_id = current_user.org.id + @template.description = params['template-desc'] + + if @template.save + redirect_to admin_template_template_path(@template), notice: _('Information was successfully created.') + else + @hash = @template.to_hash + flash[:notice] = failed_create_error(@template, _('template')) + render action: "admin_new" + end + end + + + # DELETE /org/admin/templates/:id/admin_destroy + # ----------------------------------------------------- + def admin_destroy + @template = Template.find(params[:id]) + authorize @template + + current = Template.current(@template.dmptemplate_id) + + # Only allow the current version to be destroyed + if current == @template + if @template.destroy + redirect_to admin_index_template_path + else + @hash = @template.to_hash + flash[:notice] = failed_destroy_error(@template, _('template')) + render admin_template_template_path(@template) + end + else + flash[:notice] = _('You cannot delete historical versions of this template.') + redirect_to admin_index_template_path + end + end + + # GET /org/admin/templates/:id/admin_template_history + # ----------------------------------------------------- + def admin_template_history + @template = Template.find(params[:id]) + authorize @template + @templates = Template.where(dmptemplate_id: @template.dmptemplate_id).order(:version) + @current = Template.current(@template.dmptemplate_id) + end + +end diff --git a/app/controllers/token_permission_types_controller.rb b/app/controllers/token_permission_types_controller.rb index 3500374..345bf1f 100644 --- a/app/controllers/token_permission_types_controller.rb +++ b/app/controllers/token_permission_types_controller.rb @@ -1,10 +1,12 @@ class TokenPermissionTypesController < ApplicationController + respond_to :html + + ## + # GET - Lists all TokenPermissionTypes available to the user + # also lists their description def index authorize TokenPermissionType @user = current_user - @token_types = @user.organisation.token_permission_types - respond_to do |format| - format.html - end + @token_types = @user.org.token_permission_types end end \ No newline at end of file diff --git a/app/controllers/user_identifiers_controller.rb b/app/controllers/user_identifiers_controller.rb new file mode 100644 index 0000000..6b78c8e --- /dev/null +++ b/app/controllers/user_identifiers_controller.rb @@ -0,0 +1,23 @@ +class UserIdentifiersController < ApplicationController + respond_to :html + after_action :verify_authorized + + # DELETE /users/identifiers + # --------------------------------------------------------------------- + def destroy + authorize UserIdentifier + user = User.find(current_user.id) + identifier = UserIdentifier.find(params[:id]) + + # If the requested identifier belongs to the current user remove it + if user.user_identifiers.include?(identifier) + identifier.destroy! + flash[:notice] = _('Successfully unlinked your account from %{is}.') % {is: identifier.identifier_scheme.description} + else + flash[:notice] = _('Unable to unlink your account from %{is}.') % {is: identifier.identifier_scheme.description} + end + + redirect_to edit_user_registration_path + end + +end diff --git a/app/controllers/users/omniauth_callback_controller.rb b/app/controllers/users/omniauth_callback_controller.rb deleted file mode 100644 index ee19c5c..0000000 --- a/app/controllers/users/omniauth_callback_controller.rb +++ /dev/null @@ -1,53 +0,0 @@ -class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController - - def shibboleth - if user_signed_in? && current_user.shibboleth_id.present? && current_user.shibboleth_id.length > 0 then - flash[:warning] = I18n.t('devise.failure.already_authenticated') - redirect_to root_path - else - auth = request.env['omniauth.auth'] || {} - eppn = auth['extra']['raw_info']['eppn'] - uid = nil - if !eppn.blank? then - uid = eppn - elsif !auth['uid'].blank? then - uid = auth['uid'] - elsif !auth['extra']['raw_info']['targeted-id'].blank? then - uid = auth['extra']['raw_info']['targeted-id'] - end - - if !uid.nil? && !uid.blank? then - s_user = User.where(shibboleth_id: uid).first - # Take out previous record if was not confirmed. - if !s_user.nil? && s_user.confirmed_at.nil? then - sign_out s_user - User.delete(s_user.id) - s_user = nil - end - - # Stops Shibboleth ID being blocked if email incorrectly entered. - if !s_user.nil? && s_user.try(:persisted?) then - flash[:notice] = I18n.t('devise.omniauth_callbacks.success', :kind => 'Shibboleth') - sign_in s_user - redirect_to root_path - else - if user_signed_in? then - current_user.update_attribute('shibboleth_id', uid) - user_id = current_user.id - sign_out current_user - session.delete(:shibboleth_data) - s_user = User.find(user_id) - sign_in s_user - redirect_to edit_user_registration_path - else - session[:shibboleth_data] = request.env['omniauth.auth'] - session[:shibboleth_data][:uid] = uid - redirect_to new_user_registration_url(:nosplash => 'true') - end - end - else - redirect_to root_path - end - end - end -end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb new file mode 100644 index 0000000..d50e397 --- /dev/null +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -0,0 +1,68 @@ +class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController + ## + # Dynamically build a handler for each omniauth provider + # ------------------------------------------------------------- + IdentifierScheme.where(active: true).each do |scheme| + define_method(scheme.name.downcase) do + handle_omniauth(scheme) + end + end + + ## + # Processes callbacks from an omniauth provider and directs the user to + # the appropriate page: + # Not logged in and uid had no match ---> Sign Up page + # Not logged in and uid had a match ---> Sign In and go to Home Page + # Signed in and uid had no match --> Save the uid and go to the Profile Page + # Signed in and uid had a match --> Go to the Home Page + # + # @scheme [IdentifierScheme] The IdentifierScheme for the provider + # ------------------------------------------------------------- + def handle_omniauth(scheme) + user = User.from_omniauth(request.env["omniauth.auth"].nil? ? request.env : request.env["omniauth.auth"]) + + # If the user isn't logged in + if current_user.nil? + # If the uid didn't have a match in the system send them to register + if user.nil? + session["devise.#{scheme.name.downcase}_data"] = request.env["omniauth.auth"] + flash[:notice] = t('identifier_schemes.new_login_success') + redirect_to new_user_registration_url + + # Otherwise sign them in + else + # Until ORCID becomes supported as a login method + if scheme.name == 'shibboleth' + set_flash_message(:notice, :success, kind: scheme.description) if is_navigational_format? + sign_in_and_redirect user, event: :authentication + else + flash[:notice] = t('identifier_schemes.new_login_success') + redirect_to new_user_registration_url + end + end + + # The user is already logged in and just registering the uid with us + else + # If the user could not be found by that uid then attach it to their record + if user.nil? + if UserIdentifier.create(identifier_scheme: scheme, + identifier: request.env["omniauth.auth"].uid, + user: current_user) + + flash[:notice] = _('Your account has been successfully linked to %{scheme}.') % { scheme: scheme.description } + else + flash[:notice] = _('Unable to link your account to %{scheme}.') % { scheme: scheme.description } + end + end + + # Redirect to the User Profile page + redirect_to edit_user_registration_path + end + end + # ------------------------------------------------------------- + + + def failure + redirect_to root_path + end +end diff --git a/app/controllers/users/omniauth_shibboleth_request_controller.rb b/app/controllers/users/omniauth_shibboleth_request_controller.rb deleted file mode 100644 index 7cb8368..0000000 --- a/app/controllers/users/omniauth_shibboleth_request_controller.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Users::OmniauthShibbolethRequestController < ApplicationController - before_filter :authenticate_user!, :only => :associate - - def redirect - if !current_user.nil? && !current_user.organisation.nil? - idp = params[:idp] || current_user.organisation.wayfless_entity - else - idp = params[:idp] - end - query_params = {target: user_omniauth_callback_path(:shibboleth)} - unless idp.blank? - query_params[:entityID] = idp - end - redirect_to "#{Rails.application.config.shibboleth_login}?#{query_params.to_query}", status: 302 - end - - def associate - # This action is protected - can only be reached if user is already logged in. - # See before_filter - redirect_to user_omniauth_callback_path(:shibboleth) - end -end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 52f9558..57b504f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,48 +1,57 @@ class UsersController < ApplicationController after_action :verify_authorized + respond_to :html + ## + # GET - List of all users for an organisation + # Displays number of roles[was project_group], name, email, and last sign in def admin_index authorize User - - @users = current_user.organisation.users.includes(:project_groups) - - respond_to do |format| - format.html # index.html.erb - end + @users = current_user.org.users.includes(:roles) end + ## + # GET - Displays the permissions available to the selected user + # Permissions which the user already has are pre-selected + # Selecting new permissions and saving calls the admin_update_permissions action def admin_grant_permissions - @user = User.includes(:roles).find(params[:id]) + @user = User.includes(:perms).find(params[:id]) authorize @user - user_roles = current_user.roles - @roles = user_roles & Role.where(name: [constant("user_role_types.change_org_details"),constant("user_role_types.use_api"), constant("user_role_types.modify_guidance"), constant("user_role_types.modify_templates"), constant("user_role_types.grant_permissions")]) + user_perms = current_user.perms + @perms = user_perms & [Perm.grant_permissions, Perm.modify_templates, Perm.modify_guidance, Perm.use_api, Perm.change_org_details] end + ## + # POST - updates the permissions for a user + # redirects to the admin_index action + # should add validation that the perms given are current perms of the current_user def admin_update_permissions - @user = User.includes(:roles).find(params[:id]) + @user = User.includes(:perms).find(params[:id]) authorize @user - roles_ids = params[:role_ids].blank? ? [] : params[:role_ids].map(&:to_i) - roles = Role.where( id: roles_ids) - current_user.roles.each do |role| - if @user.roles.include? role - if ! roles.include? role - @user.roles.delete(role) - if role.name == constant("user_role_types.use_api") + perms_ids = params[:perm_ids].blank? ? [] : params[:perm_ids].map(&:to_i) + perms = Perm.where( id: perms_ids) + current_user.perms.each do |perm| + if @user.perms.include? perm + if ! perms.include? perm + @user.perms.delete(perm) + if perm.id == Perm.use_api.id @user.remove_token! end end else - if roles.include? role - @user.roles << role - if role.name == constant("user_role_types.use_api") + if perms.include? perm + @user.perms << perm + if perm.name == Perm.use_api.id @user.keep_or_generate_token! end end end end - @user.save! - respond_to do |format| - format.html { redirect_to({controller: 'users', action: 'admin_index'}, {notice: I18n.t('helpers.success')})} + + if @user.save! + redirect_to({controller: 'users', action: 'admin_index'}, {notice: _('Information was successfully updated.')}) # helpers.success key does not exist, replaced with a generic string + else + flash[:notice] = failed_update_error(@user, _('user')) end end diff --git a/app/dashboards/annotation_dashboard.rb b/app/dashboards/annotation_dashboard.rb new file mode 100644 index 0000000..e26b609 --- /dev/null +++ b/app/dashboards/annotation_dashboard.rb @@ -0,0 +1,60 @@ +require "administrate/base_dashboard" + +class AnnotationDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + org: Field::BelongsTo, + question: Field::BelongsTo, + id: Field::Number, + text: Field::Text, + type: Field::String.with_options(searchable: false), + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :org, + :question, + :id, + :text, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :org, + :question, + :id, + :text, + :type, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :org, + :question, + :text, + :type, + ].freeze + + # Overwrite this method to customize how annotations are displayed + # across all pages of the admin dashboard. + # + # def display_resource(annotation) + # "Annotation ##{annotation.id}" + # end +end diff --git a/app/dashboards/answer_dashboard.rb b/app/dashboards/answer_dashboard.rb new file mode 100644 index 0000000..ad7df7f --- /dev/null +++ b/app/dashboards/answer_dashboard.rb @@ -0,0 +1,69 @@ +require "administrate/base_dashboard" + +class AnswerDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + question: Field::BelongsTo, + user: Field::BelongsTo, + plan: Field::BelongsTo, + notes: Field::HasMany, + question_options: Field::HasMany, + id: Field::Number, + text: Field::Text, + created_at: Field::DateTime, + updated_at: Field::DateTime, + lock_version: Field::Number, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :question, + :user, + :plan, + :notes, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :question, + :user, + :plan, + :notes, + :question_options, + :id, + :text, + :created_at, + :updated_at, + :lock_version, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :question, + :user, + :plan, + :notes, + :question_options, + :text, + :lock_version, + ].freeze + + # Overwrite this method to customize how answers are displayed + # across all pages of the admin dashboard. + # + # def display_resource(answer) + # "Answer ##{answer.id}" + # end +end diff --git a/app/dashboards/exported_plan_dashboard.rb b/app/dashboards/exported_plan_dashboard.rb new file mode 100644 index 0000000..47b352e --- /dev/null +++ b/app/dashboards/exported_plan_dashboard.rb @@ -0,0 +1,60 @@ +require "administrate/base_dashboard" + +class ExportedPlanDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + plan: Field::BelongsTo, + user: Field::BelongsTo, + setting_objects: Field::HasMany.with_options(class_name: "Settings::Template"), + id: Field::Number, + format: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :plan, + :user, + :setting_objects, + :id, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :plan, + :user, + :setting_objects, + :id, + :format, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :plan, + :user, + :setting_objects, + :format, + ].freeze + + # Overwrite this method to customize how exported plans are displayed + # across all pages of the admin dashboard. + # + # def display_resource(exported_plan) + # "ExportedPlan ##{exported_plan.id}" + # end +end diff --git a/app/dashboards/guidance_dashboard.rb b/app/dashboards/guidance_dashboard.rb new file mode 100644 index 0000000..8e6427f --- /dev/null +++ b/app/dashboards/guidance_dashboard.rb @@ -0,0 +1,66 @@ +require "administrate/base_dashboard" + +class GuidanceDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + guidance_group: Field::BelongsTo, + themes: Field::HasMany, + guidance_groups: Field::HasMany, + id: Field::Number, + text: Field::Text, + created_at: Field::DateTime, + updated_at: Field::DateTime, + question_id: Field::Number, + published: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :guidance_group, + :themes, + :guidance_groups, + :id, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :guidance_group, + :themes, + :guidance_groups, + :id, + :text, + :created_at, + :updated_at, + :question_id, + :published, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :guidance_group, + :themes, + :guidance_groups, + :text, + :question_id, + :published, + ].freeze + + # Overwrite this method to customize how guidances are displayed + # across all pages of the admin dashboard. + # + # def display_resource(guidance) + # "Guidance ##{guidance.id}" + # end +end diff --git a/app/dashboards/guidance_group_dashboard.rb b/app/dashboards/guidance_group_dashboard.rb new file mode 100644 index 0000000..a8a83cc --- /dev/null +++ b/app/dashboards/guidance_group_dashboard.rb @@ -0,0 +1,67 @@ +require "administrate/base_dashboard" + +class GuidanceGroupDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + org: Field::BelongsTo, + guidances: Field::HasMany, + id: Field::Number, + name: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + optional_subset: Field::Boolean, + published: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :org, + :guidances, + :id, + :name, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :org, + :guidances, + :id, + :name, + :created_at, + :updated_at, + :optional_subset, + :published, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :org, + :guidances, + :name, + :optional_subset, + :published, + ].freeze + + # Overwrite this method to customize how guidance groups are displayed + # across all pages of the admin dashboard. + # + # def display_resource(guidance_group) + # "GuidanceGroup ##{guidance_group.id}" + # end + + def display_resource(guidance_group) + guidance_group.name + end +end diff --git a/app/dashboards/identifier_scheme_dashboard.rb b/app/dashboards/identifier_scheme_dashboard.rb new file mode 100644 index 0000000..7dc1dca --- /dev/null +++ b/app/dashboards/identifier_scheme_dashboard.rb @@ -0,0 +1,68 @@ +require "administrate/base_dashboard" + +class IdentifierSchemeDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + user_identifiers: Field::HasMany, + users: Field::HasMany, + id: Field::Number, + name: Field::String, + description: Field::String, + active: Field::Boolean, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :name, + :description, + :user_identifiers, + :users, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :user_identifiers, + :users, + :id, + :name, + :description, + :active, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :user_identifiers, + :users, + :name, + :description, + :active, + ].freeze + + # Overwrite this method to customize how identifier schemes are displayed + # across all pages of the admin dashboard. + # + # def display_resource(identifier_scheme) + # "IdentifierScheme ##{identifier_scheme.id}" + # end + + def display_resource(identifier_scheme) + identifier_scheme.description + end + +end diff --git a/app/dashboards/language_dashboard.rb b/app/dashboards/language_dashboard.rb new file mode 100644 index 0000000..c888a7d --- /dev/null +++ b/app/dashboards/language_dashboard.rb @@ -0,0 +1,68 @@ +require "administrate/base_dashboard" + +class LanguageDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + users: Field::HasMany, + orgs: Field::HasMany, + id: Field::Number, + abbreviation: Field::String, + description: Field::String, + name: Field::String, + default_language: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :abbreviation, + :name, + :users, + :orgs, + :default_language, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :users, + :orgs, + :id, + :abbreviation, + :description, + :name, + :default_language, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + # :users, + # :orgs, + :abbreviation, + :description, + :name, + :default_language, + ].freeze + + # Overwrite this method to customize how languages are displayed + # across all pages of the admin dashboard. + # + # def display_resource(language) + # "Language ##{language.id}" + # end + + def display_resource(language) + language.abbreviation + end + +end diff --git a/app/dashboards/note_dashboard.rb b/app/dashboards/note_dashboard.rb new file mode 100644 index 0000000..5912418 --- /dev/null +++ b/app/dashboards/note_dashboard.rb @@ -0,0 +1,63 @@ +require "administrate/base_dashboard" + +class NoteDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + answer: Field::BelongsTo, + user: Field::BelongsTo, + id: Field::Number, + text: Field::Text, + archived: Field::Boolean, + archived_by: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :answer, + :user, + :id, + :text, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :answer, + :user, + :id, + :text, + :archived, + :archived_by, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :answer, + :user, + :text, + :archived, + :archived_by, + ].freeze + + # Overwrite this method to customize how notes are displayed + # across all pages of the admin dashboard. + # + # def display_resource(note) + # "Note ##{note.id}" + # end +end diff --git a/app/dashboards/org_dashboard.rb b/app/dashboards/org_dashboard.rb new file mode 100644 index 0000000..c00db7b --- /dev/null +++ b/app/dashboards/org_dashboard.rb @@ -0,0 +1,115 @@ +require "administrate/base_dashboard" + +class OrgDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + language: Field::BelongsTo, + guidance_groups: Field::HasMany, + templates: Field::HasMany, + users: Field::HasMany, + annotations: Field::HasMany, + token_permission_types: Field::HasMany, + id: Field::Number, + name: Field::String, + abbreviation: Field::String, + target_url: Field::String, + wayfless_entity: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + parent_id: Field::Number, + is_other: Field::Boolean, + sort_name: Field::String, + banner_text: Field::Text, + logo_file_name: Field::String, + region_id: Field::Number, + logo_uid: Field::String, + logo_name: Field::String, + contact_email: Field::String, + org_type: Field::Number, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :name, + :abbreviation, + :language, + :guidance_groups, + :templates, + :contact_email, + :org_type, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :name, + :abbreviation, + :language, + :guidance_groups, + :templates, + :contact_email, + :org_type, + :users, + :annotations, + :token_permission_types, + :id, + :target_url, + :wayfless_entity, + :created_at, + :updated_at, + :parent_id, + :is_other, + :sort_name, + :banner_text, + :logo_file_name, + :region_id, + :logo_uid, + :logo_name, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :language, + :guidance_groups, +# :templates, +# :users, +# :annotations, + :token_permission_types, + :name, + :abbreviation, + :target_url, + :wayfless_entity, + :parent_id, + :is_other, + :sort_name, + :banner_text, + :logo_file_name, + :region_id, + :logo_uid, + :logo_name, + :contact_email, + :org_type, + ].freeze + + # Overwrite this method to customize how orgs are displayed + # across all pages of the admin dashboard. + # + # def display_resource(org) + # "Org ##{org.id}" + # end + + def display_resource(org) + org.name + end +end diff --git a/app/dashboards/perm_dashboard.rb b/app/dashboards/perm_dashboard.rb new file mode 100644 index 0000000..dc9e20b --- /dev/null +++ b/app/dashboards/perm_dashboard.rb @@ -0,0 +1,59 @@ +require "administrate/base_dashboard" + +class PermDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + users: Field::HasMany, + id: Field::Number, + name: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :id, + :name, + :users, + :created_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :id, + :name, + :users, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ +# :users, + :name, + ].freeze + + # Overwrite this method to customize how perms are displayed + # across all pages of the admin dashboard. + # + # def display_resource(perm) + # "Perm ##{perm.id}" + # end + + def display_resource(perm) + perm.name + end + +end diff --git a/app/dashboards/phase_dashboard.rb b/app/dashboards/phase_dashboard.rb new file mode 100644 index 0000000..966961b --- /dev/null +++ b/app/dashboards/phase_dashboard.rb @@ -0,0 +1,72 @@ +require "administrate/base_dashboard" + +class PhaseDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + template: Field::BelongsTo, + sections: Field::HasMany, + questions: Field::HasMany, + id: Field::Number, + title: Field::String, + description: Field::Text, + number: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + slug: Field::String, + modifiable: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :template, + :sections, + :questions, + :id, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :template, + :sections, + :questions, + :id, + :title, + :description, + :number, + :created_at, + :updated_at, + :slug, + :modifiable, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :template, + :sections, + :questions, + :title, + :description, + :number, + :slug, + :modifiable, + ].freeze + + # Overwrite this method to customize how phases are displayed + # across all pages of the admin dashboard. + # + # def display_resource(phase) + # "Phase ##{phase.id}" + # end +end diff --git a/app/dashboards/plan_dashboard.rb b/app/dashboards/plan_dashboard.rb new file mode 100644 index 0000000..cb3b724 --- /dev/null +++ b/app/dashboards/plan_dashboard.rb @@ -0,0 +1,120 @@ +require "administrate/base_dashboard" + +class PlanDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + template: Field::BelongsTo, + phases: Field::HasMany, + sections: Field::HasMany, + questions: Field::HasMany, + themes: Field::HasMany, + answers: Field::HasMany, + notes: Field::HasMany, + roles: Field::HasMany, + users: Field::HasMany, + plans_guidance_groups: Field::HasMany, + guidance_groups: Field::HasMany, + exported_plans: Field::HasMany, + setting_objects: Field::HasMany.with_options(class_name: "Settings::Template"), + id: Field::Number, + project_id: Field::Number, + title: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + slug: Field::String, + grant_number: Field::String, + identifier: Field::String, + description: Field::Text, + principal_investigator: Field::String, + principal_investigator_identifier: Field::String, + data_contact: Field::String, + funder_name: Field::String, + visibility: Field::String.with_options(searchable: false), + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :template, + :phases, + :sections, + :questions, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :template, + :phases, + :sections, + :questions, + :themes, + :answers, + :notes, + :roles, + :users, + :plans_guidance_groups, + :guidance_groups, + :exported_plans, + :setting_objects, + :id, + :project_id, + :title, + :created_at, + :updated_at, + :slug, + :grant_number, + :identifier, + :description, + :principal_investigator, + :principal_investigator_identifier, + :data_contact, + :funder_name, + :visibility, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :template, + :phases, + :sections, + :questions, + :themes, + :answers, + :notes, + :roles, + :users, + :plans_guidance_groups, + :guidance_groups, + :exported_plans, + :setting_objects, + :project_id, + :title, + :slug, + :grant_number, + :identifier, + :description, + :principal_investigator, + :principal_investigator_identifier, + :data_contact, + :funder_name, + :visibility, + ].freeze + + # Overwrite this method to customize how plans are displayed + # across all pages of the admin dashboard. + # + # def display_resource(plan) + # "Plan ##{plan.id}" + # end +end diff --git a/app/dashboards/plan_guidance_group_dashboard.rb b/app/dashboards/plan_guidance_group_dashboard.rb new file mode 100644 index 0000000..5e659c0 --- /dev/null +++ b/app/dashboards/plan_guidance_group_dashboard.rb @@ -0,0 +1,57 @@ +require "administrate/base_dashboard" + +class PlanGuidanceGroupDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + plan: Field::BelongsTo, + guidance_group: Field::BelongsTo, + id: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + selected: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :plan, + :guidance_group, + :id, + :created_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :plan, + :guidance_group, + :id, + :created_at, + :updated_at, + :selected, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :plan, + :guidance_group, + :selected, + ].freeze + + # Overwrite this method to customize how plan guidance groups are displayed + # across all pages of the admin dashboard. + # + # def display_resource(plans_guidance_group) + # "PlanGuidanceGroup ##{plans_guidance_group.id}" + # end +end diff --git a/app/dashboards/question_dashboard.rb b/app/dashboards/question_dashboard.rb new file mode 100644 index 0000000..af3d8bb --- /dev/null +++ b/app/dashboards/question_dashboard.rb @@ -0,0 +1,84 @@ +require "administrate/base_dashboard" + +class QuestionDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + answers: Field::HasMany, + question_options: Field::HasMany, + annotations: Field::HasMany, + themes: Field::HasMany, + section: Field::BelongsTo, + question_format: Field::BelongsTo, + id: Field::Number, + text: Field::Text, + default_value: Field::Text, + guidance: Field::Text, + number: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + option_comment_display: Field::Boolean, + modifiable: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :answers, + :question_options, + :annotations, + :themes, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :answers, + :question_options, + :annotations, + :themes, + :section, + :question_format, + :id, + :text, + :default_value, + :guidance, + :number, + :created_at, + :updated_at, + :option_comment_display, + :modifiable, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :answers, + :question_options, + :annotations, + :themes, + :section, + :question_format, + :text, + :default_value, + :guidance, + :number, + :option_comment_display, + :modifiable, + ].freeze + + # Overwrite this method to customize how questions are displayed + # across all pages of the admin dashboard. + # + # def display_resource(question) + # "Question ##{question.id}" + # end +end diff --git a/app/dashboards/question_format_dashboard.rb b/app/dashboards/question_format_dashboard.rb new file mode 100644 index 0000000..76bbff3 --- /dev/null +++ b/app/dashboards/question_format_dashboard.rb @@ -0,0 +1,63 @@ +require "administrate/base_dashboard" + +class QuestionFormatDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + questions: Field::HasMany, + id: Field::Number, + title: Field::String, + description: Field::Text, + created_at: Field::DateTime, + updated_at: Field::DateTime, + option_based: Field::Boolean, + formattype: Field::String.with_options(searchable: false), + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :questions, + :id, + :title, + :description, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :questions, + :id, + :title, + :description, + :created_at, + :updated_at, + :option_based, + :formattype, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :questions, + :title, + :description, + :option_based, + :formattype, + ].freeze + + # Overwrite this method to customize how question formats are displayed + # across all pages of the admin dashboard. + # + # def display_resource(question_format) + # "QuestionFormat ##{question_format.id}" + # end +end diff --git a/app/dashboards/question_option_dashboard.rb b/app/dashboards/question_option_dashboard.rb new file mode 100644 index 0000000..967a91d --- /dev/null +++ b/app/dashboards/question_option_dashboard.rb @@ -0,0 +1,63 @@ +require "administrate/base_dashboard" + +class QuestionOptionDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + question: Field::BelongsTo, + answers: Field::HasMany, + id: Field::Number, + text: Field::String, + number: Field::Number, + is_default: Field::Boolean, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :question, + :answers, + :id, + :text, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :question, + :answers, + :id, + :text, + :number, + :is_default, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :question, + :answers, + :text, + :number, + :is_default, + ].freeze + + # Overwrite this method to customize how question options are displayed + # across all pages of the admin dashboard. + # + # def display_resource(question_option) + # "QuestionOption ##{question_option.id}" + # end +end diff --git a/app/dashboards/region_dashboard.rb b/app/dashboards/region_dashboard.rb new file mode 100644 index 0000000..851ad0e --- /dev/null +++ b/app/dashboards/region_dashboard.rb @@ -0,0 +1,62 @@ +require "administrate/base_dashboard" + +class RegionDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + sub_regions: Field::HasMany.with_options(class_name: "Region"), + super_region: Field::BelongsTo.with_options(class_name: "Region"), + id: Field::Number, + abbreviation: Field::String, + description: Field::String, + name: Field::String, + super_region_id: Field::Number, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :sub_regions, + :super_region, + :id, + :abbreviation, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :sub_regions, + :super_region, + :id, + :abbreviation, + :description, + :name, + :super_region_id, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :sub_regions, + :super_region, + :abbreviation, + :description, + :name, + :super_region_id, + ].freeze + + # Overwrite this method to customize how regions are displayed + # across all pages of the admin dashboard. + # + # def display_resource(region) + # "Region ##{region.id}" + # end +end diff --git a/app/dashboards/role_dashboard.rb b/app/dashboards/role_dashboard.rb new file mode 100644 index 0000000..0d8b9ea --- /dev/null +++ b/app/dashboards/role_dashboard.rb @@ -0,0 +1,57 @@ +require "administrate/base_dashboard" + +class RoleDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + user: Field::BelongsTo, + plan: Field::BelongsTo, + id: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + access: Field::Number, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :user, + :plan, + :id, + :created_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :user, + :plan, + :id, + :created_at, + :updated_at, + :access, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :user, + :plan, + :access, + ].freeze + + # Overwrite this method to customize how roles are displayed + # across all pages of the admin dashboard. + # + # def display_resource(role) + # "Role ##{role.id}" + # end +end diff --git a/app/dashboards/section_dashboard.rb b/app/dashboards/section_dashboard.rb new file mode 100644 index 0000000..2dfb78b --- /dev/null +++ b/app/dashboards/section_dashboard.rb @@ -0,0 +1,72 @@ +require "administrate/base_dashboard" + +class SectionDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + phase: Field::BelongsTo, + organisation: Field::BelongsTo, + questions: Field::HasMany, + id: Field::Number, + title: Field::String, + description: Field::Text, + number: Field::Number, + created_at: Field::DateTime, + updated_at: Field::DateTime, + published: Field::Boolean, + modifiable: Field::Boolean, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :phase, + :organisation, + :questions, + :id, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :phase, + :organisation, + :questions, + :id, + :title, + :description, + :number, + :created_at, + :updated_at, + :published, + :modifiable, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :phase, + :organisation, + :questions, + :title, + :description, + :number, + :published, + :modifiable, + ].freeze + + # Overwrite this method to customize how sections are displayed + # across all pages of the admin dashboard. + # + # def display_resource(section) + # "Section ##{section.id}" + # end +end diff --git a/app/dashboards/splash_log_dashboard.rb b/app/dashboards/splash_log_dashboard.rb new file mode 100644 index 0000000..ed549aa --- /dev/null +++ b/app/dashboards/splash_log_dashboard.rb @@ -0,0 +1,51 @@ +require "administrate/base_dashboard" + +class SplashLogDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + destination: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :id, + :destination, + :created_at, + :updated_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :id, + :destination, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :destination, + ].freeze + + # Overwrite this method to customize how splash logs are displayed + # across all pages of the admin dashboard. + # + # def display_resource(splash_log) + # "SplashLog ##{splash_log.id}" + # end +end diff --git a/app/dashboards/template_dashboard.rb b/app/dashboards/template_dashboard.rb new file mode 100644 index 0000000..cfaa8e0 --- /dev/null +++ b/app/dashboards/template_dashboard.rb @@ -0,0 +1,101 @@ +require "administrate/base_dashboard" + +class TemplateDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + org: Field::BelongsTo, + plans: Field::HasMany, + phases: Field::HasMany, + sections: Field::HasMany, + questions: Field::HasMany, + customizations: Field::HasMany.with_options(class_name: "Template"), + dmptemplate: Field::BelongsTo.with_options(class_name: "Template"), + setting_objects: Field::HasMany.with_options(class_name: "Settings::Template"), + id: Field::Number, + title: Field::String, + description: Field::Text, + published: Field::Boolean, + locale: Field::String, + is_default: Field::Boolean, + created_at: Field::DateTime, + updated_at: Field::DateTime, + version: Field::Number, + visibility: Field::Number, + customization_of: Field::Number, + dmptemplate_id: Field::Number, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :title, + :description, + :org, + :plans, + :phases, + :sections, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :org, + :plans, + :phases, + :sections, + :questions, + :customizations, + :dmptemplate, + :setting_objects, + :id, + :title, + :description, + :published, + :locale, + :is_default, + :created_at, + :updated_at, + :version, + :visibility, + :customization_of, + :dmptemplate_id, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :org, + :plans, + :phases, + :sections, + :questions, + :customizations, + :dmptemplate, + :setting_objects, + :title, + :description, + :published, + :locale, + :is_default, + :version, + :visibility, + :customization_of, + :dmptemplate_id, + ].freeze + + # Overwrite this method to customize how templates are displayed + # across all pages of the admin dashboard. + # + # def display_resource(template) + # "Template ##{template.id}" + # end +end diff --git a/app/dashboards/theme_dashboard.rb b/app/dashboards/theme_dashboard.rb new file mode 100644 index 0000000..40f8b3d --- /dev/null +++ b/app/dashboards/theme_dashboard.rb @@ -0,0 +1,63 @@ +require "administrate/base_dashboard" + +class ThemeDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + questions: Field::HasMany, + guidances: Field::HasMany, + id: Field::Number, + title: Field::String, + description: Field::Text, + created_at: Field::DateTime, + updated_at: Field::DateTime, + locale: Field::String, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :questions, + :guidances, + :id, + :title, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :questions, + :guidances, + :id, + :title, + :description, + :created_at, + :updated_at, + :locale, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :questions, + :guidances, + :title, + :description, + :locale, + ].freeze + + # Overwrite this method to customize how themes are displayed + # across all pages of the admin dashboard. + # + # def display_resource(theme) + # "Theme ##{theme.id}" + # end +end diff --git a/app/dashboards/token_permission_type_dashboard.rb b/app/dashboards/token_permission_type_dashboard.rb new file mode 100644 index 0000000..93deb0f --- /dev/null +++ b/app/dashboards/token_permission_type_dashboard.rb @@ -0,0 +1,61 @@ +require "administrate/base_dashboard" + +class TokenPermissionTypeDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + orgs: Field::HasMany, + id: Field::Number, + token_type: Field::String, + text_description: Field::Text, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :orgs, + :id, + :token_type, + :text_description, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :orgs, + :id, + :token_type, + :text_description, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :orgs, + :token_type, + :text_description, + ].freeze + + # Overwrite this method to customize how token permission types are displayed + # across all pages of the admin dashboard. + # + # def display_resource(token_permission_type) + # "TokenPermissionType ##{token_permission_type.id}" + # end + def display_resource(token_permission_type) + "#{token_permission_type.token_type}: #{token_permission_type.text_description}" + end + +end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb new file mode 100644 index 0000000..4ba23ad --- /dev/null +++ b/app/dashboards/user_dashboard.rb @@ -0,0 +1,160 @@ +require "administrate/base_dashboard" + +class UserDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + invited_by: Field::Polymorphic, + perms: Field::HasMany, + language: Field::BelongsTo, + org: Field::BelongsTo, + answers: Field::HasMany, + notes: Field::HasMany, + exported_plans: Field::HasMany, + roles: Field::HasMany, + plans: Field::HasMany, + user_identifiers: Field::HasMany, + identifier_schemes: Field::HasMany, + setting_objects: Field::HasMany.with_options(class_name: "Settings::PlanList"), + id: Field::Number, + firstname: Field::String, + surname: Field::String, + email: Field::String, + orcid_id: Field::String, + shibboleth_id: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + encrypted_password: Field::String, + reset_password_token: Field::String, + reset_password_sent_at: Field::DateTime, + remember_created_at: Field::DateTime, + sign_in_count: Field::Number, + current_sign_in_at: Field::DateTime, + last_sign_in_at: Field::DateTime, + current_sign_in_ip: Field::String, + last_sign_in_ip: Field::String, + confirmation_token: Field::String, + confirmed_at: Field::DateTime, + confirmation_sent_at: Field::DateTime, + invitation_token: Field::String, + invitation_created_at: Field::DateTime, + invitation_sent_at: Field::DateTime, + invitation_accepted_at: Field::DateTime, + other_organisation: Field::String, + accept_terms: Field::Boolean, + api_token: Field::String, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :firstname, + :surname, + :email, + :org, + :perms, + :confirmed_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :firstname, + :surname, + :email, + :org, + :perms, + :confirmed_at, + :id, + :invited_by, + :language, + :answers, + :notes, + :exported_plans, + :roles, + :plans, + :user_identifiers, + :identifier_schemes, + :orcid_id, + :shibboleth_id, + :created_at, + :updated_at, + :encrypted_password, + :reset_password_token, + :reset_password_sent_at, + :remember_created_at, + :sign_in_count, + :current_sign_in_at, + :last_sign_in_at, + :current_sign_in_ip, + :last_sign_in_ip, + :confirmation_token, + :confirmation_sent_at, + :invitation_token, + :invitation_created_at, + :invitation_sent_at, + :invitation_accepted_at, + :other_organisation, + :accept_terms, + :api_token, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ +# :invited_by, + :perms, + :language, + :org, +# :answers, +# :notes, +# :exported_plans, +# :roles, +# :plans, + :user_identifiers, + :identifier_schemes, + :firstname, + :surname, + :email, + :orcid_id, + :shibboleth_id, +# :encrypted_password, +# :reset_password_token, +# :reset_password_sent_at, +# :remember_created_at, +# :sign_in_count, +# :current_sign_in_at, +# :last_sign_in_at, +# :current_sign_in_ip, +# :last_sign_in_ip, +# :confirmation_token, +# :confirmed_at, +# :confirmation_sent_at, +# :invitation_token, +# :invitation_created_at, +# :invitation_sent_at, +# :invitation_accepted_at, +# :other_organisation, + :accept_terms, +# :api_token, + ].freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + # def display_resource(user) + # "User ##{user.id}" + # end + + def display_resource(user) + "#{user.firstname} #{user.surname} (##{user.id})" + end +end diff --git a/app/dashboards/user_identifier_dashboard.rb b/app/dashboards/user_identifier_dashboard.rb new file mode 100644 index 0000000..fc6d73e --- /dev/null +++ b/app/dashboards/user_identifier_dashboard.rb @@ -0,0 +1,62 @@ +require "administrate/base_dashboard" + +class UserIdentifierDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + user: Field::BelongsTo, + identifier_scheme: Field::BelongsTo, + id: Field::Number, + identifier: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :user, + :identifier_scheme, + :id, + :identifier, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :user, + :identifier_scheme, + :id, + :identifier, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [ + :user, + :identifier_scheme, + :identifier, + ].freeze + + # Overwrite this method to customize how user identifiers are displayed + # across all pages of the admin dashboard. + # + # def display_resource(user_identifier) + # "UserIdentifier ##{user_identifier.id}" + # end + + def display_resource(user_identifier) + user_identifier.identifier + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 56f99a5..8c37586 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,41 +1,33 @@ module ApplicationHelper - def resource_name - :user - end - - def resource - @resource ||= User.new - end - - def devise_mapping - @devise_mapping ||= Devise.mappings[:user] - end - - def javascript(*files) - content_for(:head) { javascript_include_tag(*files) } - end - def link_to_add_object(name, f, association, css_class, i) - new_object = f.object.class.reflect_on_association(association).klass.new - fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder| - j = i + 1 - new_object.number = j - render(association.to_s.singularize + "_fields", :f => builder) - end - link_to_function(name, "add_object(this, \"#{association}\", \"#{escape_javascript(fields)}\")", :class => css_class) + def resource_name + :user + end + + # --------------------------------------------------------------------------- + def resource + @resource ||= User.new + end + + # --------------------------------------------------------------------------- + def devise_mapping + @devise_mapping ||= Devise.mappings[:user] end - def link_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys - - function = block_given? ? update_page(&block) : args[0] || '' - onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" - href = html_options[:href] || '#' - - content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + # --------------------------------------------------------------------------- + def javascript(*files) + content_for(:head) { javascript_include_tag(*files) } end - def hash_to_json_object(obj_name, hash) + # --------------------------------------------------------------------------- + def hash_to_js_json_variable(obj_name, hash) "".html_safe end + + # Determines whether or not the URL path passed matches with the full path (including params) of the last URL requested. + # see http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-fullpath for details + def isActivePage(path) + return request.fullpath() == path + end + end diff --git a/app/helpers/plans_helper.rb b/app/helpers/plans_helper.rb new file mode 100644 index 0000000..cf5a0c6 --- /dev/null +++ b/app/helpers/plans_helper.rb @@ -0,0 +1,90 @@ +module PlansHelper + + # Build variable column headings for the project list + # -------------------------------------------------------- + def plan_list_column_heading(column) + if column.kind_of?(Array) + heading = (column.first.kind_of?(String) ? column.first : _(' - ')) + + elsif column.kind_of?(String) + heading = column + + else + heading = _(' - ') + end + + klass = (['name', 'description'].include?(heading) ? :dmp_th_big : :dmp_th_small) + + content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) # parametrised YAML keys are no longer possible with gettext, TODO + end + + # Populate a variable column for the project list + # -------------------------------------------------------- + def plan_list_column_body(column, plan) + + col = (column.kind_of?(Array) ? column[0] : column) + + klass, content = case col + when 'name' + [ "dmp_td_big", link_to(plan.title, plan_path(plan), class: "dmp_table_link") ] + when 'owner' + user = plan.owner + text = if user.nil? + _(' - ') + elsif user == current_user + _('Me') + else + user.name + end + + [ "tmp_td_small", text ] + when 'shared' + shared_num = plan.users.count - 1 + text = shared_num > 0 ? (_('Yes') + " (with #{shared_num} people) ") : _('No') # Hardcoded strings are not internationalised + [ "dmp_td_small", text ] + when 'visibility' + text = if plan.visibility == 'organisationally_visible' + _('Organisational') + elsif plan.visibility == 'publicly_visible' + _('Public') + elsif plan.visibility == 'is_test' + _('Test/Practice') + elsif plan.visibility == 'privately_visible' + _('Private') + end + ["dmp_td_small", text ] + when 'last_edited' + [ "dmp_td_small", l(plan.latest_update.to_date, formats: :short) ] + when 'description' + [ "dmp_td_medium", (plan.try(col) || _(' - ')) ] + when 'non_link_name' + [ "dmp_td_big", plan.title ] + when 'template' + ["dmp_td_big", plan.template.title] + when 'organisation' + ["dmp_td_medium", plan.template.org.name] # This will trigger 2 queries for each function call, i.e. one for templates and another for orgs tables + else + [ "dmp_td_small", (plan.try(col) || _(' - ')) ] + end + content_tag(:td, content, class: klass) + end + + # Shows whether the user has default, template-default or custom settings + # for the given plan. + # -------------------------------------------------------- + def plan_settings_indicator(plan) + plan_settings = plan.super_settings(:export) + template_settings = plan.template.try(:settings, :export) + + key = if plan_settings.try(:value?) + plan_settings.formatting == template_settings.formatting ? "template_formatting" : "custom_formatting" + elsif template_settings.try(:value?) + "template_formatting" + else + "default_formatting" + end + + content_tag(:small, t("helpers.settings.plans.#{key}")) + end + +end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb deleted file mode 100644 index 4679053..0000000 --- a/app/helpers/projects_helper.rb +++ /dev/null @@ -1,76 +0,0 @@ -module ProjectsHelper - - # Build variable column headings for the project list - # -------------------------------------------------------- - def project_list_column_heading(column) - if column.kind_of?(Array) - heading = (column.first.kind_of?(String) ? column.first : t("helpers.project.columns.unknown")) - - elsif column.kind_of?(String) - heading = column - - else - heading = t("helpers.project.columns.unknown") - end - - klass = (['name', 'description'].include?(heading) ? :dmp_th_big : :dmp_th_small) - - content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) - end - - # Populate a variable column for the project list - # -------------------------------------------------------- - def project_list_column_body(column, project) - - col = (column.kind_of?(Array) ? column[0] : column) - - klass, content = case col - when 'name' - [ "dmp_td_big", link_to(project.title, project_path(project), class: "dmp_table_link") ] - - when 'owner' - user = project.owner - - text = if user.nil? - "Unknown" - elsif user == current_user - t("helpers.me") - else - user.name - end - - [ "tmp_td_small", text ] - when 'shared' - shared_num = project.project_groups.count - 1 - text = shared_num > 0 ? (t("helpers.yes_label") + " (with #{shared_num} people) ") : t("helpers.no_label") - [ "dmp_td_small", text ] - when 'last_edited' - [ "dmp_td_small", l(project.latest_update.to_date, formats: :short) ] - when 'description' - [ "dmp_td_medium", (project.try(col) || "Unknown") ] - else - [ "dmp_td_small", (project.try(col) || "Unknown") ] - end - - content_tag(:td, content, class: klass) - end - - # Shows whether the user has default, template-default or custom settings - # for the given plan. - # -------------------------------------------------------- - def plan_settings_indicator(plan) - plan_settings = plan.super_settings(:export) - template_settings = plan.project.dmptemplate.try(:settings, :export) - - key = if plan_settings.try(:value?) - plan_settings.formatting == template_settings.formatting ? "template_formatting" : "custom_formatting" - elsif template_settings.try(:value?) - "template_formatting" - else - "default_formatting" - end - - content_tag(:small, t("helpers.settings.plans.#{key}")) - end - -end diff --git a/app/helpers/settings_template_helper.rb b/app/helpers/settings_template_helper.rb new file mode 100644 index 0000000..255c95e --- /dev/null +++ b/app/helpers/settings_template_helper.rb @@ -0,0 +1,27 @@ +module SettingsTemplateHelper + # Retrieves an msgstr for a given admin_field + def admin_field_t(admin_field) + if Settings::Template::VALID_ADMIN_FIELDS.include?(admin_field) + if admin_field == 'project_name' + return _('Plan Name') + elsif admin_field == 'project_identifier' + return _('Plan ID') + elsif admin_field == 'grant_title' + return _('Grant number') + elsif admin_field == 'principal_investigator' + return _('Principal Investigator / Researcher') + elsif admin_field == 'project_data_contact' + return _('Plan Data Contact') + elsif admin_field == 'project_description' + return _('Plan Description') + elsif admin_field == 'funder' + return _('Funder') + elsif admin_field == 'institution' + return _('Institution') + elsif admin_field == 'orcid' + return _('Your ORCID') + end + end + return _('Unknown column name.') + end +end \ No newline at end of file diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index e11166a..f679ba2 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,24 +1,47 @@ class UserMailer < ActionMailer::Base - default from: I18n.t('helpers.main_email.from') + default from: Rails.configuration.branding[:organisation][:email] - def sharing_notification(project_group) - @project_group = project_group - mail(to: @project_group.user.email, subject: I18n.t('helpers.main_email.access_given')) + def welcome_notification(user) + @user = user + FastGettext.with_locale FastGettext.default_locale do + mail(to: @user.email, + subject: "#{_('Welcome to')} #{Rails.configuration.branding[:application][:name]}") + end + end + + def sharing_notification(role, user) + @role = role + @user = user + FastGettext.with_locale FastGettext.default_locale do + mail(to: @role.user.email, + subject: "#{_('A Data Management Plan in ')} #{Rails.configuration.branding[:application][:name]} #{_(' has been shared with you')}") + end end - def permissions_change_notification(project_group) - @project_group = project_group - mail(to: @project_group.user.email, subject: I18n.t('helpers.main_email.permission_changed')) + def permissions_change_notification(role, current_user) + @role = role + @current_user = current_user + FastGettext.with_locale FastGettext.default_locale do + mail(to: @role.user.email, + subject: "#{_('Changed permissions on a DMP in')} #{Rails.configuration.branding[:application][:name]}") + end end - def project_access_removed_notification(user, project) + def project_access_removed_notification(user, plan, current_user) @user = user - @project = project - mail(to: @user.email, subject: I18n.t('helpers.main_email.access_removed')) + @plan = plan + @current_user = current_user + FastGettext.with_locale FastGettext.default_locale do + mail(to: @user.email, + subject: "#{_('Permissions removed on a DMP in')} #{Rails.configuration.branding[:application][:name]}") + end end def api_token_granted_notification(user) @user = user - mail(to: @user.email, subject: I18n.t('helper.api_mail_subject')) + FastGettext.with_locale FastGettext.default_locale do + mail(to: @user.email, + subject: "#{_('API rights in')} #{Rails.configuration.branding[:application][:name]}") + end end -end \ No newline at end of file +end diff --git a/app/models/ability.rb b/app/models/ability.rb deleted file mode 100644 index e283051..0000000 --- a/app/models/ability.rb +++ /dev/null @@ -1,38 +0,0 @@ -class Ability - include GlobalHelpers - include CanCan::Ability - - def initialize(user) - # Define abilities for the passed in user here. For example: - # - user ||= User.new # guest user (not logged in) - if user.has_role? constant("user_role_types.super_admin") - can :manage, :all - else - can :read, :all - end - - can :manage_settings, User do |viewed_user| - viewed_user.present? && user.id == viewed_user.id - end - # - # The first argument to `can` is the action you are giving the user - # permission to do. - # If you pass :manage it will apply to every action. Other common actions - # here are :read, :create, :update and :destroy. - # - # The second argument is the resource the user can perform the action on. - # If you pass :all it will apply to every resource. Otherwise pass a Ruby - # class of the resource. - # - # The third argument is an optional hash of conditions to further filter the - # objects. - # For example, here the user can only update published articles. - # - # can :update, Article, :published => true - # - # See the wiki for details: - # https://github.com/ryanb/cancan/wiki/Defining-Abilities - - end -end diff --git a/app/models/admin_user.rb b/app/models/admin_user.rb deleted file mode 100644 index 511e649..0000000 --- a/app/models/admin_user.rb +++ /dev/null @@ -1,4 +0,0 @@ -class AdminUser < ActiveRecord::Base - devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable - attr_accessible :email, :password, :password_confirmation, :remember_me -end diff --git a/app/models/annotation.rb b/app/models/annotation.rb new file mode 100644 index 0000000..8ea44dd --- /dev/null +++ b/app/models/annotation.rb @@ -0,0 +1,40 @@ +class Annotation < ActiveRecord::Base + enum type: [ :example_answer, :guidance] + ## + # Associations + belongs_to :org + belongs_to :question + + ## + # I liked type as the name for the enum so overriding inheritance column + self.inheritance_column = nil + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :org_id, :question_id, :text, :type, + :org, :question, :as => [:default, :admin] + + + validates :question, :org, presence: {message: _("can't be blank")} + + ## + # returns the text from the annotation + # + # @return [String] the text from the annotation + def to_s + "#{text}" + end + + + ## + # deep copy the given annotation and all it's associations + # + # @params [Annotation] annotation to be deep copied + # @return [Annotation] the saved, copied annotation + def self.deep_copy(annotation) + annotation_copy = annotation.dup + annotation_copy.save! + return annotation_copy + end +end \ No newline at end of file diff --git a/app/models/answer.rb b/app/models/answer.rb index cadb66d..d46ad59 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -1,16 +1,59 @@ class Answer < ActiveRecord::Base - #associations between tables + ## + # Associations belongs_to :question belongs_to :user belongs_to :plan + has_many :notes, dependent: :destroy + has_and_belongs_to_many :question_options, join_table: "answers_question_options" -# accepts_nested_attributes_for :question -# accepts_nested_attributes_for :plan - - has_and_belongs_to_many :options, join_table: "answers_options" - - attr_accessible :text, :plan_id, :question_id, :user_id, :option_ids , :as => [:default, :admin] - - + has_many :notes + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :text, :plan_id, :lock_version, :question_id, :user_id, :question_option_ids, + :question, :user, :plan, :question_options, :notes, :note_ids, :id, + :as => [:default, :admin] + + ## + # Validations +# validates :user, :plan, :question, presence: true +# +# # Make sure there is only one answer per question! +# validates :question, uniqueness: {scope: [:plan], +# message: I18n.t('helpers.answer.only_one_per_question')} +# +# # The answer MUST have a text value if the question is NOT option based or a question_option if +# # it is option based. +# validates :text, presence: true, if: Proc.new{|a| +# (a.question.nil? ? false : !a.question.question_format.option_based?) +# } +# validates :question_options, presence: true, if: Proc.new{|a| +# (a.question.nil? ? false : a.question.question_format.option_based?) +# } +# +# # Make sure the plan and question are associated with the same template! +# validates :plan, :question, answer_for_correct_template: true + + # This method helps to decide if an answer option (:radiobuttons, :checkbox, etc ) in form views should be checked or not + # Returns true if the given option_id is present in question_options, otherwise returns false + def has_question_option(option_id) + self.question_option_ids.include?(option_id) + end + + # Returns true if the answer is valid and false otherwise. If the answer's question is option_based, it is checked if exist + # any question_option selected. For non option_based (e.g. textarea or textfield), it is checked the presence of text + def is_valid? + if self.question.present? + if self.question.question_format.option_based? + return !self.question_options.empty? + else # (e.g. textarea or textfield question formats) + return self.text.present? + end + else + return false + end + end end diff --git a/app/models/comment.rb b/app/models/comment.rb deleted file mode 100644 index b4af9f9..0000000 --- a/app/models/comment.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Comment < ActiveRecord::Base - - #associations between tables - belongs_to :question - - #fields - attr_accessible :question_id, :text, :user_id, :archived, :plan_id, :archived_by, :as => [:default, :admin] - - - - def to_s - "#{text}" - end - -end diff --git a/app/models/dmptemplate.rb b/app/models/dmptemplate.rb deleted file mode 100644 index 981b585..0000000 --- a/app/models/dmptemplate.rb +++ /dev/null @@ -1,163 +0,0 @@ -class Dmptemplate < ActiveRecord::Base - include GlobalHelpers - - attr_accessible :id, :organisation_id, :description, :published, :title, :user_id, :locale, - :is_default, :guidance_group_ids, :as => [:default, :admin] - - #associations between tables - has_many :phases - has_many :versions, through: :phases - has_many :sections, through: :versions - has_many :questions, through: :sections - has_many :projects - - #has_many :guidances needs to be removed and checked - - belongs_to :organisation - - has_and_belongs_to_many :guidance_groups, join_table: "dmptemplates_guidance_groups" - - accepts_nested_attributes_for :guidance_groups - accepts_nested_attributes_for :phases - accepts_nested_attributes_for :organisation - accepts_nested_attributes_for :projects - - - has_settings :export, class_name: 'Settings::Dmptemplate' do |s| - s.key :export, defaults: Settings::Dmptemplate::DEFAULT_SETTINGS - end - - ## - # Converts a DMPtemplate object into a string containing it's title - # - # @return [String] the title of the DMPtemplate - def to_s - "#{title}" - end - - ## - # takes a type or organisation and returns all published templates from - # organisations of that type - # - # @param ot [String] name of an organisation type e.g. founder - # @return [Array] list of published dmptemplates - def self.templates_org_type(ot) - # DISCUSS - This function other than the check for the template being published - # is a superclass for the below funders_templates - new_org_obejcts = OrganisationType.find_by( name: ot ).organisations - - org_templates = Array.new - new_org_obejcts.each do |neworg| - org_templates += neworg.dmptemplates.where("published = ?", true) - end - - return org_templates - end - - ## - # returns all templates from all organisations of the Organisation_Type funder - # - # @return [Array] all templates from funder organisations - def self.funders_templates - new_org_obejcts = OrganisationType.find_by(name: GlobalHelpers.constant("organisation_types.funder")).organisations - org_templates = Array.new - - new_org_obejcts.each do |neworg| - org_templates += neworg.dmptemplates - end - - return org_templates - end - - ## - # returns all institutional templates bellowing to the given organisation - # - # @param org_id [integer] the integer id for an organisation - # @return [Array] all templates from a user's organisation - def self.own_institutional_templates(org_id) - # DISCUSS - Why is this done by scanning organisation_id's from the templates - # yet all other calls are done by finding an organisation, and using the - # has_many relationship to find the dmptemplates? - # - A possible answer is that there may be deleted organisations which we are - # serching for templates for. - # - A standardised behavior on querries, wether through active reccord or the - # where, should maybe be thought of/decided upon - new_templates = self.where("organisation_id = ?", org_id) - return new_templates - end - - ## - # returns an array with all funders and of the given organisations's - # institutional templates - # - # @param org_id [integer] the integer id for an organisation - # @return [Array] all templates from the template's organisation - # or from a funder organisation - def self.funders_and_own_templates(org_id) - funders_templates = self.funders_templates - # DISCUSS - Here we internationalise the word funder. There is code in the - # api that just uses the english word funder. Why are we internationalising - # the database querry, and do I need to change things like this elsewhere? - - #verify if org type is not a funder - current_org = Organisation.find(org_id) - if current_org.organisation_type.name != GlobalHelpers.constant("organisation_types.funder") then - own_institutional_templates = self.own_institutional_templates(org_id) - else - own_institutional_templates = [] - end - - templates_list = Array.new - templates_list += own_institutional_templates - templates_list += funders_templates - templates_list = templates_list.sort_by { |f| f['title'].downcase } - - return templates_list - end - - ## - # Returns the string name of the organisation type of the organisation who - # owns this dmptemplate - # - # @return [string] the string name of an organisation type - def org_type - org_type = organisation.organisation_type.name - return org_type - end - - ## - # Verify if a template has customisation by given organisation - # - # @param org_id [integer] the integer id for an organisation - # @param temp [dmptemplate] a template object - # @return [Boolean] true if temp has customisation by the given organisation - def has_customisations?(org_id, temp) - # EXPLAIN - I dont Understand the data model here. If the template isnt - # owned by the organisation, how can it make changes to a section? - # Why cant the owner make customisations? - if temp.organisation_id != org_id then - temp.phases.each do |phase| - phase.versions.each do |version| - version.sections.each do |section| - return true if section.organisation_id == org_id - end - end - return false - end - else - return false - end - end - - ## - # verify if there are any publish version for the template - # - # @return [Boolean] true if there is a published version for the template - def has_published_versions? - phases.each do |phase| - return true if !phase.latest_published_version.nil? - end - return false - end - -end diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index 2ea784b..0bd9ef1 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -1,142 +1,187 @@ class ExportedPlan < ActiveRecord::Base include GlobalHelpers + include SettingsTemplateHelper - attr_accessible :plan_id, :user_id, :format, :as => [:default, :admin] +# TODO: REMOVE AND HANDLE ATTRIBUTE SECURITY IN THE CONTROLLER! + attr_accessible :plan_id, :user_id, :format, :user, :plan, :as => [:default, :admin] #associations between tables belongs_to :plan belongs_to :user - VALID_FORMATS = ['csv', 'html', 'json', 'pdf', 'text', 'xml', 'docx'] + VALID_FORMATS = ['csv', 'html', 'pdf', 'text', 'docx'] - validates :format, inclusion: { in: VALID_FORMATS, message: I18n.t('helpers.plan.export.not_valid_format') } + validates :format, inclusion: { + in: VALID_FORMATS, + message: -> (object, data) do + _('%{value} is not a valid format') % { :value => data[:value] } + end + } + validates :plan, :format, presence: {message: _("can't be blank")} # Store settings with the exported plan so it can be recreated later # if necessary (otherwise the settings associated with the plan at a # given time can be lost) - has_settings :export, class_name: 'Settings::Dmptemplate' do |s| - s.key :export, defaults: Settings::Dmptemplate::DEFAULT_SETTINGS + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS end - # Getters to match Settings::Dmptemplate::VALID_ADMIN_FIELDS +# TODO: Consider removing the accessor methods, they add no value. The view/controller could +# just access the value directly from the project/plan: exported_plan.plan.project.title + + # Getters to match Settings::Template::VALID_ADMIN_FIELDS def project_name - name = self.plan.project.title - name += " - #{self.plan.title}" if self.plan.project.dmptemplate.phases.count > 1 + name = self.plan.template.title + name += " - #{self.plan.title}" if self.plan.template.phases.count > 1 name end def project_identifier - self.plan.project.identifier + self.plan.identifier end def grant_title - self.plan.project.grant_number + self.plan.grant_number end def principal_investigator - self.plan.project.principal_investigator + self.plan.principal_investigator end def project_data_contact - self.plan.project.data_contact + self.plan.data_contact end def project_description - self.plan.project.description + self.plan.description + end + + def owner + self.plan.roles.to_a.select{ |role| role.creator? }.first.user end def funder - org = self.plan.project.dmptemplate.try(:organisation) - org.name if org.present? && org.organisation_type.try(:name) == constant("organisation_types.funder") + org = self.plan.template.try(:org) + org.name if org.present? && org.funder? end def institution - plan.project.organisation.try(:name) + plan.owner.org.try(:name) end - # sections taken from fields settings + def orcid + scheme = IdentifierScheme.find_by(name: 'orcid') + if self.owner.nil? + '' + else + orcid = self.owner.user_identifiers.where(identifier_scheme: scheme).first + (orcid.nil? ? '' : orcid.identifier) + end + end + def sections - sections = self.plan.sections - - return [] if questions.empty? - - section_ids = questions.pluck(:section_id).uniq - sections = sections.select {|section| section_ids.member?(section.id) } - - sections.sort_by(&:number) + self.phase_id ||= self.plan.template.phases.first.id + Section.where({phase_id: phase_id}).order(:number) end def questions_for_section(section_id) - questions.where(section_id: section_id) + Question.where(id: questions).where(section_id: section_id).order(:number) end def admin_details @admin_details ||= self.settings(:export).fields[:admin] end + # Retrieves the title field + def title + self.settings(:export).title + end + # Export formats def as_csv CSV.generate do |csv| - csv << ["Section","Question","Answer","Selected option(s)","Answered by","Answered at"] + csv << [_('Section'),_('Question'),_('Answer'),_('Selected option(s)'),_('Answered by'),_('Answered at')] self.sections.each do |section| - self.questions_for_section(section).each do |question| - answer = self.plan.answer(question.id) - options_string = answer.options.collect {|o| o.text}.join('; ') - - csv << [section.title, sanitize_text(question.text), sanitize_text(answer.text), options_string, answer.try(:user).try(:name), answer.created_at] + questions = self.questions_for_section(section) + if questions.present? + questions.each do |question| + answer = self.plan.answer(question.id) + q_format = question.question_format + if q_format.option_based? + options_string = answer.question_options.collect {|o| o.text}.join('; ') + else + options_string = '' + end + csv << [ + section.title, + sanitize_text(question.text), + question.option_comment_display ? sanitize_text(answer.text) : '', + options_string, + user.name, + answer.updated_at + ] + end end end end end def as_txt - output = "#{self.plan.project.title}\n\n#{self.plan.version.phase.title}\n" + output = "#{self.plan.title}\n\n#{self.plan.template.title}\n" + output += "\n"+_('Details')+"\n\n" - -puts "SETTINGS: #{self.plan.inspect}" - - output += "\nDetails:\n#{self.plan.settings[:export][:fields][:admin].collect{|f| f.to_s}.join('\n')}\n" + self.admin_details.each do |at| + value = self.send(at) + if value.present? + output += admin_field_t(at.to_s) + ": " + value + "\n" + else + output += admin_field_t(at.to_s) + ": " + _('-') + "\n" + end + end self.sections.each do |section| - output += "\n#{section.title}\n" + questions = self.questions_for_section(section) + if questions.present? + output += "\n#{section.title}\n" + questions.each do |question| + qtext = sanitize_text( question.text.gsub(/
  • /, ' * ') ) + output += "\n* #{qtext}" + answer = self.plan.answer(question.id, false) - self.questions_for_section(section).each do |question| - qtext = sanitize_text( question.text.gsub(/
  • /, ' * ') ) - output += "\n#{qtext}\n" - answer = self.plan.answer(question.id, false) - - if answer.nil? || answer.text.nil? then - output += I18n.t('helpers.plan.export.pdf.question_not_answered')+ "\n" - else - output += answer.options.collect {|o| o.text}.join("\n") - if question.option_comment_display == true then - output += "\n#{sanitize_text(answer.text)}\n" + if answer.nil? + output += _('Question not answered.')+ "\n" else - output += "\n" + q_format = question.question_format + if q_format.option_based? + output += answer.question_options.collect {|o| o.text}.join("\n") + if question.option_comment_display + output += "\n#{sanitize_text(answer.text)}\n" + end + else + output += "\n#{sanitize_text(answer.text)}\n" + end end end end end - output end private - + # Returns an Array of question_ids for the exported settings stored for a plan def questions - @questions ||= begin - question_settings = self.settings(:export).fields[:questions] - - return [] if question_settings.is_a?(Array) && question_settings.empty? - - questions = if question_settings.present? && question_settings != :all - Question.where(id: question_settings) + question_settings = self.settings(:export).fields[:questions] + @questions ||= if question_settings.present? + if question_settings == :all + Question.where(section_id: self.plan.sections.collect { |s| s.id }).pluck(:id) + elsif question_settings.is_a?(Array) + question_settings else - Question.where(section_id: self.plan.sections.collect {|s| s.id }) + [] end - - questions.order(:number) + else + [] end end diff --git a/app/models/file_type.rb b/app/models/file_type.rb deleted file mode 100644 index 7c836dc..0000000 --- a/app/models/file_type.rb +++ /dev/null @@ -1,3 +0,0 @@ -class FileType < ActiveRecord::Base - #attr_accessible :name, :icon_location, :icon_name, :icon_size -end diff --git a/app/models/file_upload.rb b/app/models/file_upload.rb deleted file mode 100644 index 7cf325c..0000000 --- a/app/models/file_upload.rb +++ /dev/null @@ -1,7 +0,0 @@ -class FileUpload < ActiveRecord::Base - #attr_accessible :file_type_id, :description, :location, :name, :published, :size, :title - - #associations between tables - belongs_to :file_type - -end diff --git a/app/models/guidance.rb b/app/models/guidance.rb index ac1e886..8ba321b 100644 --- a/app/models/guidance.rb +++ b/app/models/guidance.rb @@ -3,28 +3,29 @@ # This class keeps the information organisations enter to support users when answering questions. # It always belongs to a guidance group class and it can be linked directly to a question or through one or more themes # [+Created:+] 07/07/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center +# [+Copyright:+] Digital Curation Centre and California Digital Library class Guidance < ActiveRecord::Base include GlobalHelpers - #associations between tables - attr_accessible :text, :question_id, :published, :as => [:default, :admin] - attr_accessible :guidance_group_ids, :as => [:default, :admin] - attr_accessible :theme_ids, :as => [:default, :admin] - - belongs_to :question - - #belongs_to :dmptemplate - #belongs_to :theme - - has_and_belongs_to_many :guidance_groups, join_table: "guidance_in_group" + ## + # Associations + belongs_to :guidance_group has_and_belongs_to_many :themes, join_table: "themes_in_guidance" +# depricated, but required for migration "single_group_for_guidance" + #has_and_belongs_to_many :guidance_groups, join_table: "guidance_in_group" - accepts_nested_attributes_for :themes - accepts_nested_attributes_for :guidance_groups + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + + + + validates :text, presence: {message: _("can't be blank")} ## @@ -32,12 +33,12 @@ # # @param org_id [Integer] the integer id for an organisation # @return [Boolean] true if this guidance is in a group belonging to the specified organisation, false otherwise - def in_group_belonging_to?(organisation_id) - guidance_groups.each do |guidance_group| - if guidance_group.organisation_id == organisation_id - return true - end - end + def in_group_belonging_to?(org_id) + unless guidance_group.nil? + if guidance_group.org.id == org_id + return true + end + end return false end @@ -46,10 +47,11 @@ # # @param org_id [Integer] the integer id for an organisation # @return [Array] list of guidance - def self.by_organisation(org_id) + def self.by_org(org_id) org_guidance = [] - Organisation.find_by(id: org_id).guidance_groups.each do |group| - org_guidance += group.guidances + # TODO: re-write below querry when guidance_in_group removed from model + Org.find_by(id: org_id).guidance_groups.each do |group| + org_guidance += Guidance.where(guidance_group_id: group.id) end return org_guidance end @@ -84,25 +86,21 @@ guidance = Guidance.find_by(id: id) viewable = false - # guidances may belong to many guidance groups, so we check the above case for each - guidance.guidance_groups.each do |guidance_group| - - # guidances are viewable if they are owned by any of the user's organisations - user.organisations.each do |organisation| - - if guidance_group.organisation.id == organisation.id + unless guidance.nil? + unless guidance.guidance_group.nil? + # guidances are viewable if they are owned by the user's org + if guidance.guidance_group.org == user.org viewable = true end - end + # guidance groups are viewable if they are owned by the Managing Curation Center + if Org.managing_orgs.include?(guidance.guidance_group.org) + viewable = true + end - # guidance groups are viewable if they are owned by the Managing Curation Center - if guidance_group.organisation.id == Organisation.find_by( name: GlobalHelpers.constant("organisation_types.managing_organisation")).id - viewable = true - end - - # guidance groups are viewable if they are owned by a funder - if guidance_group.organisation.organisation_type == OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - viewable = true + # guidance groups are viewable if they are owned by a funder + if Org.funders.include?(guidance.guidance_group.org) + viewable = true + end end end @@ -119,26 +117,17 @@ # @param user [User] a user object # @return [Array] a list of all "viewable" guidances to a user def self.all_viewable(user) - managing_groups = (Organisation.find_by name: GlobalHelpers.constant("organisation_types.managing_organisation")).guidance_groups + managing_groups = Org.includes(guidance_groups: :guidances).managing_orgs.collect{|o| o.guidance_groups} # find all groups owned by a Funder organisation - funder_groups = [] - funders = OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - funders.organisations.each do |funder| - funder_groups += funder.guidance_groups - end + funder_groups = Org.includes(guidance_groups: :guidances).funders.collect{|org| org.guidance_groups} # find all groups owned by any of the user's organisations - organisation_groups = [] - user.organisations.each do |organisation| - organisation_groups += organisation.guidance_groups - end + organisation_groups = user.org.guidance_groups + # find all guidances belonging to any of the viewable groups - all_viewable_guidances = [] - all_viewable_groups = managing_groups + funder_groups + organisation_groups - all_viewable_groups.each do |group| - all_viewable_guidances += group.guidances - end + all_viewable_groups = (managing_groups + funder_groups + organisation_groups).flatten + all_viewable_guidances = all_viewable_groups.collect{|group| group.guidances} # pass the list of viewable guidances to the view - return all_viewable_guidances + return all_viewable_guidances.flatten end end diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index d9102a4..ee3e685 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -1,26 +1,31 @@ class GuidanceGroup < ActiveRecord::Base include GlobalHelpers - - #associations between tables - belongs_to :organisation - - has_and_belongs_to_many :guidances, join_table: "guidance_in_group" - - has_and_belongs_to_many :projects, join_table: "project_guidance" - has_and_belongs_to_many :dmptemplates, join_table: "dmptemplates_guidance_groups" - - accepts_nested_attributes_for :dmptemplates - - attr_accessible :organisation_id, :name, :optional_subset, :published, :as => [:default, :admin] - attr_accessible :dmptemplate_ids, :as => [:default, :admin] + ## + # Associations + belongs_to :org + has_many :guidances, dependent: :destroy + has_and_belongs_to_many :plans, join_table: :plans_guidance_groups + # depricated but needed for migration "single_group_for_guidance" + # has_and_belongs_to_many :guidances, join_table: "guidance_in_group" + ## - # Converts a guidance group to a string containing the display name + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :org_id, :name, :optional_subset, :published, :org, :guidances, + :as => [:default, :admin] + + validates :name, :org, presence: {message: _("can't be blank")} + + + # EVALUATE CLASS AND INSTANCE METHODS BELOW # - # @return [String] the name of the organisation, with or without the name of the guidance group - def to_s - "#{display_name}" - end + # What do they do? do they do it efficiently, and do we need them? + + + + + ## # Converts the current guidance group to a string containing the display name. @@ -30,10 +35,10 @@ # # @return [String] the display name for the guidance group def display_name - if organisation.guidance_groups.count > 1 - return "#{organisation.name}: #{name}" + if org.guidance_groups.count > 1 + return "#{org.name}: #{name}" else - return organisation.name + return org.name end end @@ -42,14 +47,20 @@ # # @param excluded_orgs [Array] a list of organisations to exclude in the result # @return [Array] a list of guidance groups - def self.guidance_groups_excluding(excluded_orgs) - excluded_org_ids = Array.new - excluded_orgs.each do |org| - excluded_org_ids << org.id - end - return_orgs = GuidanceGroup.where("organisation_id NOT IN (?)", excluded_org_ids) - return return_orgs - end + def self.guidance_groups_excluding(excluded_orgs) + excluded_org_ids = Array.new + + if excluded_orgs.is_a?(Array) + excluded_orgs.each do |org| + excluded_org_ids << org.id + end + else + excluded_org_ids << excluded_orgs + end + + return_orgs = GuidanceGroup.where("org_id NOT IN (?)", excluded_org_ids) + return return_orgs + end ## # Returns whether or not a given user can view a given guidance group @@ -61,22 +72,20 @@ # @param id [Integer] the integer id for a guidance group # @param user [User] a user object # @return [Boolean] true if the specified user can view the specified guidance group, false otherwise - def self.can_view?(user, id) - guidance_group = GuidanceGroup.find_by(id: id) + def self.can_view?(user, guidance_group) viewable = false - # groups are viewable if they are owned by any of the user's organisations - if guidance_group.organisation == user.organisation + if guidance_group.org == user.org viewable = true end # groups are viewable if they are owned by the managing curation center - Organisation.where( name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_group| - if guidance_group.organisation.id == managing_group.id + Org.managing_orgs.each do |managing_group| + if guidance_group.org.id == managing_group.id viewable = true end end # groups are viewable if they are owned by a funder - if guidance_group.organisation.organisation_type == OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) + if guidance_group.org.funder? viewable = true end @@ -94,22 +103,16 @@ # @return [Array] a list of all "viewable" guidance groups to a user def self.all_viewable(user) # first find all groups owned by the Managing Curation Center - managing_org_groups = [] - Organisation.where( name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_org| - managing_org_groups = managing_org_groups + managing_org.guidance_groups - end + managing_org_groups = Org.includes(guidance_groups: [guidances: :themes]).managing_orgs.collect{|org| org.guidance_groups} # find all groups owned by a Funder organisation - funder_groups = [] - funders = OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - funders.organisations.each do |funder| - funder_groups = funder_groups + funder.guidance_groups - end - organisation_groups = [user.organisation.guidance_groups] - + funder_groups = Org.includes(:guidance_groups).funders.collect{|org| org.guidance_groups} + + organisation_groups = [user.org.guidance_groups] + # pass this organisation guidance groups to the view with respond_with @all_viewable_groups all_viewable_groups = managing_org_groups + funder_groups + organisation_groups - all_viewable_groups = all_viewable_groups.uniq{|x| x.id} + all_viewable_groups = all_viewable_groups.flatten.uniq return all_viewable_groups end end diff --git a/app/models/identifier_scheme.rb b/app/models/identifier_scheme.rb new file mode 100644 index 0000000..d07aafc --- /dev/null +++ b/app/models/identifier_scheme.rb @@ -0,0 +1,6 @@ +class IdentifierScheme < ActiveRecord::Base + has_many :user_identifiers + has_many :users, through: :user_identifiers + + validates :name, uniqueness: {message: _("must be unique")}, presence: {message: _("can't be blank")} +end \ No newline at end of file diff --git a/app/models/language.rb b/app/models/language.rb index 65477be..2d02783 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -1,5 +1,14 @@ class Language < ActiveRecord::Base + ## + # Associations has_many :users + has_many :orgs - validates :abbreviation, presence: true, uniqueness: true + ## + # Validations + # Cannot do FastGettext translations here because we constantize LANGUAGES in initializers/constants.rb + validates :abbreviation, presence: {message: "can't be blank"}, uniqueness: {message: "must be unique"} + + scope :sorted_by_abbreviation, -> { all.order(:abbreviation) } + scope :default, -> { where(default_language: true).first } end \ No newline at end of file diff --git a/app/models/note.rb b/app/models/note.rb new file mode 100644 index 0000000..4341c2a --- /dev/null +++ b/app/models/note.rb @@ -0,0 +1,14 @@ +class Note < ActiveRecord::Base + ## + # Associations + belongs_to :answer + belongs_to :user + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :text, :user_id, :answer_id, :archived, :archived_by, + :answer, :user, :as => [:default, :admin] + + validates :text, :answer, :user, presence: {message: _("can't be blank")} +end diff --git a/app/models/option.rb b/app/models/option.rb deleted file mode 100644 index 87dfc46..0000000 --- a/app/models/option.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Option < ActiveRecord::Base - - #associations between tables - belongs_to :question - - has_many :option_warnings, :dependent => :destroy - - has_and_belongs_to_many :answers, join_table: "answers_options" - - attr_accessible :text, :question_id, :is_default, :number, :as => [:default, :admin] - - def to_s - "#{text}" - end -end \ No newline at end of file diff --git a/app/models/option_warning.rb b/app/models/option_warning.rb deleted file mode 100644 index d67709f..0000000 --- a/app/models/option_warning.rb +++ /dev/null @@ -1,12 +0,0 @@ -class OptionWarning < ActiveRecord::Base - - #associations between tables - belongs_to :option - belongs_to :organisation - - attr_accessible :text, :option_id, :organisation_id, :as => [:default, :admin] - - def to_s - "#{text}" - end -end \ No newline at end of file diff --git a/app/models/org.rb b/app/models/org.rb new file mode 100644 index 0000000..9abbe2e --- /dev/null +++ b/app/models/org.rb @@ -0,0 +1,243 @@ +class Org < ActiveRecord::Base + include GlobalHelpers + include FlagShihTzu + extend Dragonfly::Model::Validations + + ## + # Sort order: Name ASC + default_scope { order(name: :asc) } + + + ## + # Associations +# belongs_to :organisation_type # depricated, but cannot be removed until migration run + belongs_to :language + has_many :guidance_groups + has_many :templates + has_many :users + has_many :annotations + + has_and_belongs_to_many :token_permission_types, join_table: "org_token_permissions", unique: true + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :abbreviation, :banner_text, :logo, :remove_logo, + :logo_file_name, :name, :target_url, + :organisation_type_id, :wayfless_entity, :parent_id, :sort_name, + :token_permission_type_ids, :language_id, :contact_email, + :language, :org_type, :region, :token_permission_types, + :guidance_group_ids, :is_other, :region_id, :logo_uid, :logo_name + + ## + # Validators + validates :contact_email, email: true, allow_nil: true + validates :name, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} + # allow validations for logo upload + dragonfly_accessor :logo do + after_assign :resize_image + end + validates_property :height, of: :logo, in: (0..100), message: _("height must be less than 100px") + validates_property :format, of: :logo, in: ['jpeg', 'png', 'gif','jpg','bmp'], message: _("must be one of the following formats: jpeg, jpg, png, gif, bmp") + validates_size_of :logo, maximum: 500.kilobytes, message: _("can't be larger than 500KB") + + ## + # Define Bit Field values + # Column org_type + has_flags 1 => :institution, + 2 => :funder, + 3 => :organisation, + 4 => :research_institute, + 5 => :project, + 6 => :school, + column: 'org_type' + + # Predefined queries for retrieving the managain organisation and funders + scope :managing_orgs, -> { where(abbreviation: Rails.configuration.branding[:organisation][:abbreviation]) } + scope :funders, -> { where(org_type: 2) } + scope :institutions, -> { where(org_type: 1) } + + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + # Determines the locale set for the organisation + # @return String or nil + def get_locale + if !self.language.nil? + return self.language.abbreviation + else + return nil + end + end + +# TODO: Should these be hardcoded? Also, an Org can currently be multiple org_types at one time. +# For example you can do: funder = true; project = true; school = true +# Calling type in the above scenario returns "Funder" which is a bit misleading +# Is FlagShihTzu's Bit flag the appropriate structure here or should we use an enum? +# Tests are setup currently to work with this issue. + ## + # returns the name of the type of the organisation as a string + # defaults to none if no org type present + # + # @return [String] + def type + if self.institution? + return "Institution" + elsif self.funder? + return "Funder" + elsif self.organisation? + return "Organisation" + elsif self.research_institute? + return "Research Institute" + elsif self.project? + return "Project" + elsif self.school? + return "School" + end + return "None" + end + + + ## + # returns the name of the organisation + # + # @return [String] + def to_s + name + end + + ## + # returns the abbreviation for the organisation if it exists, or the name if not + # + # @return [String] name or abbreviation of the organisation + def short_name + if abbreviation.nil? then + return name + else + return abbreviation + end + end + + ## + # finds all organisations who have a parent of the passed organisation type + # + # @param [String] the name of an organisation type + # @return [Array] +=begin + def self.orgs_with_parent_of_type(org_type) + parents = OrganisationType.find_by_name(org_type).organisations + children = Array.new + parents.each do |parent| + children += parent.children + end + return children + end + + ## + # returns a list of all guidance groups belonging to other organisations + # + # @return [Array] + def self.other_organisations + org_types = [GlobalHelpers.constant("organisation_types.funder")] + organisations_list = [] + org_types.each do |ot| + new_org_obejct = OrganisationType.find_by_name(ot) + + org_with_guidance = GuidanceGroup.joins(new_org_obejct.organisations) + + organisations_list = organisations_list + org_with_guidance + end + return organisations_list + end + + + ## + # returns a list of all guidance groups belonging to other organisations + # + # @return [Array] + def self.other_organisations + org_types = [GlobalHelpers.constant("organisation_types.funder")] + organisations_list = [] + org_types.each do |ot| + new_org_obejct = OrganisationType.find_by_name(ot) + + org_with_guidance = GuidanceGroup.joins(new_org_obejct.organisations) + + organisations_list = organisations_list + org_with_guidance + end + return organisations_list + end + + ## + # returns a list of all sections of a given version from this organisation and it's parents + # + # @param version_id [Integer] version number of the section + # @return [Array
    ] list of sections + def all_sections(version_id) + if parent.nil? + secs = sections.where("version_id = ?", version_id) + if secs.nil? then + secs = Array.new + end + return secs + else + return sections.where("version_id = ? ", version_id).all + parent.all_sections(version_id) + end + end + + ## + # returns the guidance groups of this organisation and all of it's children + # + # @return [Array] list of guidance groups + def all_guidance_groups + ggs = guidance_groups + children.each do |c| + ggs = ggs + c.all_guidance_groups + end + return ggs + end + + ## + # returns the highest parent organisation in the tree + # + # @return [organisation] the root organisation + def root + if parent.nil? + return self + else + return parent.root + end + end +=end + + ## + # returns all published templates belonging to the organisation + # + # @return [Array] published dmptemplates + def published_templates + return templates.where("published = ?", true) + end + + def check_api_credentials + if token_permission_types.count == 0 + users.each do |user| + user.api_token = "" + user.save! + end + end + end + + private + ## + # checks size of logo and resizes if necessary + # + def resize_image + unless logo.nil? + if logo.height != 100 + self.logo = logo.thumb('x100') # resize height and maintain aspect ratio + end + end + end +end diff --git a/app/models/org_token_permission.rb b/app/models/org_token_permission.rb deleted file mode 100644 index c00a248..0000000 --- a/app/models/org_token_permission.rb +++ /dev/null @@ -1,8 +0,0 @@ -class OrgTokenPermission < ActiveRecord::Base - attr_accessible :organisation_id, :token_permission_type_id, :organisation, :token_permission_type, :as => [:default, :admin] - - #associations between tables - belongs_to :organisation - belongs_to :token_permission_type - -end diff --git a/app/models/organisation.rb b/app/models/organisation.rb deleted file mode 100644 index 5aabbf0..0000000 --- a/app/models/organisation.rb +++ /dev/null @@ -1,194 +0,0 @@ -class Organisation < ActiveRecord::Base - include GlobalHelpers - - extend Dragonfly::Model::Validations - - #associations between tables - belongs_to :organisation_type - has_many :guidance_groups - has_many :dmptemplates - has_many :sections - has_many :users - has_many :option_warnings - has_many :suggested_answers - has_and_belongs_to_many :token_permission_types, join_table: "org_token_permissions" - - belongs_to :parent, :class_name => 'Organisation' - - has_one :language - - has_many :children, :class_name => 'Organisation', :foreign_key => 'parent_id' - - accepts_nested_attributes_for :dmptemplates - accepts_nested_attributes_for :token_permission_types - - attr_accessible :abbreviation, :banner_text, :logo, :remove_logo, :domain, - :logo_file_name, :name, :stylesheet_file_id, :target_url, - :organisation_type_id, :wayfless_entity, :parent_id, :sort_name, - :token_permission_type_ids, :language_id, :contact_email - - validates :contact_email, email: true, allow_nil: true - validates :name, presence: true, uniqueness: true - - # allow validations for logo upload - dragonfly_accessor :logo do - after_assign :resize_image - end - - validates_property :height, of: :logo, in: (0..100) - validates_property :format, of: :logo, in: ['jpeg', 'png', 'gif','jpg','bmp'] - validates_size_of :logo, maximum: 500.kilobytes - - ## - # returns the name of the organisation - # - # @return [String] - def to_s - name - end - - ## - # returns the abbreviation for the organisation if it exists, or the name if not - # - # @return [String] name or abbreviation of the organisation - def short_name - if abbreviation.nil? then - return name - else - return abbreviation - end - end - - ## - # finds all organisations who have a parent of the passed organisation type - # - # @param [String] the name of an organisation type - # @return [Array] - def self.orgs_with_parent_of_type(org_type) - parents = OrganisationType.find_by_name(org_type).organisations - children = Array.new - parents.each do |parent| - children += parent.children - end - return children - end - - ## - # returns a list of all guidance groups belonging to other organisations - # - # @return [Array] - def self.other_organisations - org_types = [GlobalHelpers.constant("organisation_types.funder")] - organisations_list = [] - org_types.each do |ot| - new_org_obejct = OrganisationType.find_by_name(ot) - - org_with_guidance = GuidanceGroup.joins(new_org_obejct.organisations) - - organisations_list = organisations_list + org_with_guidance - end - return organisations_list - end - - - ## - # returns a list of all guidance groups belonging to other organisations - # - # @return [Array] - def self.other_organisations - org_types = [GlobalHelpers.constant("organisation_types.funder")] - organisations_list = [] - org_types.each do |ot| - new_org_obejct = OrganisationType.find_by_name(ot) - - org_with_guidance = GuidanceGroup.joins(new_org_obejct.organisations) - - organisations_list = organisations_list + org_with_guidance - end - return organisations_list - end - - ## - # returns a list of all sections of a given version from this organisation and it's parents - # - # @param version_id [Integer] version number of the section - # @return [Array
    ] list of sections - def all_sections(version_id) - if parent.nil? - secs = sections.where("version_id = ?", version_id) - if secs.nil? then - secs = Array.new - end - return secs - else - return sections.where("version_id = ? ", version_id).all + parent.all_sections(version_id) - end - end - - ## - # returns the guidance groups of this organisation and all of it's children - # - # @return [Array] list of guidance groups - def all_guidance_groups - ggs = guidance_groups - children.each do |c| - ggs = ggs + c.all_guidance_groups - end - return ggs - end - - ## - # returns the highest parent organisation in the tree - # - # @return [organisation] the root organisation - def root - if parent.nil? - return self - else - return parent.root - end - end - - ## - # takes in the id of, and returns an OptionWarning - # - # @param option_id [number] the id of the desired warning - # @return [OptionWarning] the specified warning - def warning(option_id) - warning = option_warnings.find_by_option_id(option_id) - if warning.nil? && !parent.nil? then - return parent.warning(option_id) - else - return warning - end - end - - ## - # returns all published templates belonging to the organisation - # - # @return [Array] published dmptemplates - def published_templates - return dmptemplates.where("published = ?", true) - end - - def check_api_credentials - if token_permission_types.count == 0 - users.each do |user| - user.api_token = "" - user.save! - end - end - end - - private - ## - # checks size of logo and resizes if necessary - # - def resize_image - unless logo.nil? - if logo.height != 100 - self.logo = logo.thumb('x100') # resize height and maintain aspect ratio - end - end - end -end diff --git a/app/models/organisation_type.rb b/app/models/organisation_type.rb deleted file mode 100644 index 20df31d..0000000 --- a/app/models/organisation_type.rb +++ /dev/null @@ -1,7 +0,0 @@ -class OrganisationType < ActiveRecord::Base - attr_accessible :description, :organisations, :name, :as => [:default, :admin] - - has_many :organisations - - validates :name, presence: true, uniqueness: true -end diff --git a/app/models/perm.rb b/app/models/perm.rb new file mode 100644 index 0000000..58aad3e --- /dev/null +++ b/app/models/perm.rb @@ -0,0 +1,32 @@ +class Perm < ActiveRecord::Base + ## + # Associations + has_and_belongs_to_many :users, :join_table => :users_perms + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + #attr_accessible :name, :as => [:default, :admin] + + validates :name, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} + + ## + # Constant perms + #ADD_ORGS = Perm.where(name: 'add_organisations').first.freeze + #CHANGE_AFFILIATION = Perm.where(name: 'change_org_affiliation').first.freeze + #GRANT_PERMISSIONS = Perm.where(name: 'grant_permissions').first.freeze + #MODIFY_TEMPLATES = Perm.where(name: 'modify_templates').first.freeze + #MODIFY_GUIDANCE = Perm.where(name: 'modify_guidance').first.freeze + #USE_API = Perm.where(name: 'use_api').first.freeze + #CHANGE_ORG_DETAILS = Perm.where(name: 'change_org_details').first.freeze + #GRANT_API = Perm.where(name: 'grant_api_to_orgs').first.freeze + + scope :add_orgs, -> {Perm.find_by(name: 'add_organisations')} + scope :change_affiliation, -> {Perm.find_by(name: 'change_org_affiliation')} + scope :grant_permissions, -> {Perm.find_by(name: 'grant_permissions')} + scope :modify_templates, -> {Perm.find_by(name: 'modify_templates')} + scope :modify_guidance, -> {Perm.find_by(name: 'modify_guidance')} + scope :use_api, -> {Perm.find_by(name: 'use_api')} + scope :change_org_details, -> {Perm.find_by(name: 'change_org_details')} + scope :grant_api, -> {Perm.find_by(name: 'grant_api_to_orgs')} +end diff --git a/app/models/phase.rb b/app/models/phase.rb index 155a86f..5c2323f 100644 --- a/app/models/phase.rb +++ b/app/models/phase.rb @@ -5,75 +5,105 @@ # [+Copyright:+] Digital Curation Centre and University of California Curation Center class Phase < ActiveRecord::Base - extend FriendlyId + ## + # Sort order: Number ASC + default_scope { order(number: :asc) } - #associations between tables - belongs_to :dmptemplate - has_many :versions, :dependent => :destroy - has_many :sections, :through => :versions, :dependent => :destroy - has_many :questions, :through => :sections, :dependent => :destroy +# extend FriendlyId + ## + # Associations + belongs_to :template + has_many :sections, -> { order(:number => :asc) }, dependent: :destroy + has_many :questions, :through => :sections, dependent: :destroy - #Link the child's data - accepts_nested_attributes_for :versions, :allow_destroy => true -# accepts_nested_attributes_for :dmptemplate + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :description, :number, :title, :template_id, + :template, :sections, :modifiable, :as => [:default, :admin] - attr_accessible :description, :number, :title, :dmptemplate_id, :as => [:default, :admin] + ## + # sluggable title + #friendly_id :title, use: [:slugged, :history, :finders] - friendly_id :title, use: [:slugged, :history, :finders] + + validates :title, :number, :template, presence: {message: _("can't be blank")} + + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + + + ## # returns the title of the phase # # @return [String] the title of the phase - def to_s - "#{title}" - end + def to_s + "#{title}" + end +# TODO: This function does not belong here anymore. It may be useless now. ## - # returns the most_recent version of this phase - # - # @return [Version] the most recent version of this phase - def latest_version - return versions.order("number DESC").last - end - - ## - # returns either the latest published version of this phase + # returns either the latest published version of this phase # also serves to verify if this phase has any published versions as returns nil # if there are no published versions # # @return [Version, nil] - def latest_published_version - pub_vers = versions.where('published = ?', true).order('updated_at DESC') - if pub_vers.any?() then - return pub_vers.first - else - return nil - end - end +# def latest_published_version +# pub_vers = versions.where('published = ?', true).order('updated_at DESC') +# if pub_vers.any?() then +# return pub_vers.first +# else +# return nil +# end +# end +# TODO: reevaluate this method. It seems like the 1st query is unecessary ## - # verify if a phase has a published version or a version with one or more sections + # verify if a phase has a published version or a version with one or more sections # # @return [Boolean] - def has_sections - versions = self.versions.where('published = ?', true).order('updated_at DESC') - if versions.any? then - version = versions.first - if !version.sections.empty? then - has_section = true - else - has_section = false - end - else - version = self.versions.order('updated_at DESC').first - if !version.sections.empty? then - has_section = true - else - has_section = false - end - end - return has_section - end +=begin + def has_sections + versions = self.versions.where('published = ?', true).order('updated_at DESC') + if versions.any? then + version = versions.first + if !version.sections.empty? then + has_section = true + else + has_section = false + end + else + version = self.versions.order('updated_at DESC').first + if !version.sections.empty? then + has_section = true + else + has_section = false + end + end + return has_section + end +=end + + ## + # deep copy the given phase and all it's associations + # + # @params [Phase] phase to be deep copied + # @return [Phase] the saved, copied phase + def self.deep_copy(phase) + phase_copy = phase.dup + phase_copy.save! + phase.sections.each do |section| + section_copy = Section.deep_copy(section) + section_copy.phase_id = phase_copy.id + section_copy.save! + end + return phase_copy + end + end diff --git a/app/models/plan.rb b/app/models/plan.rb index f25998c..f3974d2 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -1,66 +1,102 @@ class Plan < ActiveRecord::Base - attr_accessible :locked, :project_id, :version_id, :version, :plan_sections, :as => [:default, :admin] - - A4_PAGE_HEIGHT = 297 #(in mm) - A4_PAGE_WIDTH = 210 #(in mm) - ROUNDING = 5 #round estimate up to nearest 5% - FONT_HEIGHT_CONVERSION_FACTOR = 0.35278 #convert font point size to mm - FONT_WIDTH_HEIGHT_RATIO = 0.4 #Assume glyph width averages 2/5 the height - - #associations between tables - belongs_to :project - belongs_to :version - has_many :answers - has_many :plan_sections - -# accepts_nested_attributes_for :project - accepts_nested_attributes_for :answers -# accepts_nested_attributes_for :version - - has_settings :export, class_name: 'Settings::Dmptemplate' do |s| - s.key :export, defaults: Settings::Dmptemplate::DEFAULT_SETTINGS - end - - alias_method :super_settings, :settings + before_validation :set_creation_defaults ## - # Proxy through to the template settings (or defaults if this plan doesn't have - # an associated template) if there are no settings stored for this plan. - # `key` is required by rails-settings, so it's required here, too. + # Associations + belongs_to :template + has_many :phases, through: :template + has_many :sections, through: :phases + has_many :questions, through: :sections + has_many :themes, through: :questions + has_many :answers, dependent: :destroy + has_many :notes, through: :answers + has_many :roles, dependent: :destroy + has_many :users, through: :roles + has_and_belongs_to_many :guidance_groups, join_table: :plans_guidance_groups + + accepts_nested_attributes_for :template + has_many :exported_plans + + has_many :roles + + +# COMMENTED OUT THE DIRECT CONNECTION HERE TO Users to prevent assignment of users without an access_level specified (currently defaults to creator) +# has_many :users, through: :roles + + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :locked, :project_id, :version_id, :version, :plan_sections, + :exported_plans, :project, :title, :template, :grant_number, + :identifier, :principal_investigator, :principal_investigator_identifier, + :description, :data_contact, :funder_name, :visibility, :exported_plans, + :roles, :users, :org, :as => [:default, :admin] + accepts_nested_attributes_for :roles + + # public is a Ruby keyword so using publicly + enum visibility: [:organisationally_visible, :publicly_visible, :is_test, :privately_visible] + + #TODO: work out why this messes up plan creation : + # briley: Removed reliance on :users, its really on :roles (shouldn't have a plan without at least a creator right?) It should be ok like this though now +# validates :template, :title, presence: true + + ## + # Constants + A4_PAGE_HEIGHT = 297 #(in mm) + A4_PAGE_WIDTH = 210 #(in mm) + ROUNDING = 5 #round estimate up to nearest 5% + FONT_HEIGHT_CONVERSION_FACTOR = 0.35278 #convert font point size to mm + FONT_WIDTH_HEIGHT_RATIO = 0.4 #Assume glyph width averages 2/5 the height + + # Scope queries + # Note that in ActiveRecord::Enum the mappings are exposed through a class method with the pluralized attribute name (e.g visibilities rather than visibility) + scope :publicly_visible, -> { where(:visibility => visibilities[:publicly_visible]).order(:title => :asc) } + + ## + # Settings for the template + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS + end + alias_method :super_settings, :settings + + + ## + # Proxy through to the template settings (or defaults if this plan doesn't have + # an associated template) if there are no settings stored for this plan. + # `key` is required by rails-settings, so it's required here, too. # # @param key [Key] a key required by rails # @return [Settings] settings for this plan's template - def settings(key) - self_settings = self.super_settings(key) - return self_settings if self_settings.value? - self.dmptemplate.settings(key) - end + def settings(key) + self_settings = self.super_settings(key) + return self_settings if self_settings.value? +# self.dmptemplate.settings(key) + self.template.settings(key) unless self.template.nil? + end ## # returns the template for this plan, or generates an empty template and returns that # # @return [Dmptemplate] the template associated with this plan def dmptemplate - self.project.try(:dmptemplate) || Dmptemplate.new + #self.project.try(:dmptemplate) || Dmptemplate.new + self.template end - ## - # returns the title for this project as defined by the settings - # - # @return [String] the title for this project - def title - logger.debug "Title in settings: #{self.settings(:export).title}" - if self.settings(:export).title == "" - if !self.version.nil? && !self.version.phase.nil? && !self.version.phase.title? then - return self.version.phase.title - else - return I18n.t('tool_title2') - end - else - return self.settings(:export).title - end - end + + + def base_template + base = nil + t = self.template + if t.customization_of.present? + base = Template.where("dmptemplate_id = ? and created_at < ?", t.customization_of, self.created_at).order(version: :desc).first + end + return base + end + + ## # returns the most recent answer to the given question id @@ -78,69 +114,116 @@ answer.question_id = qid answer.text = question.default_value default_options = Array.new - question.options.each do |option| + question.question_options.each do |option| if option.is_default default_options << option end end - answer.options = default_options + answer.question_options = default_options end return answer end +# TODO: This just retrieves all of the guidance associated with the themes within the template +# so why are we transferring it here to the plan? ## # returns all of the sections for this version of the plan, and for the project's organisation # # @return [Array
    ,nil] either a list of sections, or nil if none were found - def sections - unless project.organisation.nil? then - sections = version.global_sections + project.organisation.all_sections(version_id) - else - sections = version.global_sections - end - return sections.uniq.sort_by &:number - end + def set_possible_guidance_groups + # find all the themes in this plan + # and get the guidance groups they belong to + ggroups = [] + self.template.phases.each do |phase| + phase.sections.each do |section| + section.questions.each do |question| + question.themes.each do |theme| + theme.guidances.each do |guidance| + ggroups << guidance.guidance_group + end + end + end + end + end + + self.guidance_groups = ggroups.uniq + end ## + # returns all of the possible guidance groups for the plan (all options to + # be selected by the user to display) + # + # @return Array + def get_guidance_group_options + # find all the themes in this plan + # and get the guidance groups they belong to + ggroups = [] + self.template.phases.each do |phase| + phase.sections.each do |section| + section.questions.each do |question| + question.themes.each do |theme| + theme.guidances.each do |guidance| + ggroups << guidance.guidance_group + end + end + end + end + end + return ggroups.uniq + end + + + + + ## # returns the guidances associated with the project's organisation, for a specified question # # @param question [Question] the question to find guidance for - # @return [Array] the list of guidances which pretain to the specified question - def guidance_for_question(question) - guidances = {} - # If project org isn't nil, get guidance by theme from any "non-subset" groups belonging to project org - unless project.organisation.nil? then - project.organisation.guidance_groups.each do |group| - if !group.optional_subset && (group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0) then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - end - # Get guidance by theme from any guidance groups selected on creation - project.guidance_groups.each do |group| - if group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0 then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - # Get guidance by question where guidance group was selected on creation or if group is organisation default - question.guidances.each do |guidance| - guidance.guidance_groups.each do |group| - if (group.organisation == project.organisation && !group.optional_subset) || project.guidance_groups.include?(group) then - guidances = self.add_guidance_to_array(guidances, group, nil, guidance) - end + # @return array of hashes with orgname, themes and the guidance itself + def guidance_for_question(question) + guidances = [] + + # add in the guidance for the template org + unless self.template.org.nil? then + self.template.org.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end end - end + end + + # add in the guidance for the user's org + unless self.owner.nil? + unless self.owner.org.nil? then + self.owner.org.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end + end + end + end - return guidances - end + # Get guidance by theme from any guidance groups currently selected + self.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end + end + + return guidances + end + + + ## # adds the given guidance to a hash indexed by a passed guidance group and theme @@ -150,233 +233,300 @@ # @param theme [Theme] the theme object for the GuidanceGroup # @param guidance [Guidance] the guidance object to be appended to the correct section of the array # @return [{GuidanceGroup => {Theme => Array}}] the updated object which was passed in - def add_guidance_to_array(guidance_array, guidance_group, theme, guidance) - if guidance_array[guidance_group].nil? then - guidance_array[guidance_group] = {} - end - if theme.nil? then - if guidance_array[guidance_group]["no_theme"].nil? then - guidance_array[guidance_group]["no_theme"] = [] - end - if !guidance_array[guidance_group]["no_theme"].include?(guidance) then - guidance_array[guidance_group]["no_theme"].push(guidance) - end - else - if guidance_array[guidance_group][theme].nil? then - guidance_array[guidance_group][theme] = [] - end - if !guidance_array[guidance_group][theme].include?(guidance) then - guidance_array[guidance_group][theme].push(guidance) - end - end + def add_guidance_to_array(guidance_array, guidance_group, theme, guidance) + if guidance_array[guidance_group].nil? then + guidance_array[guidance_group] = {} + end + if theme.nil? then + if guidance_array[guidance_group]["no_theme"].nil? then + guidance_array[guidance_group]["no_theme"] = [] + end + if !guidance_array[guidance_group]["no_theme"].include?(guidance) then + guidance_array[guidance_group]["no_theme"].push(guidance) + end + else + if guidance_array[guidance_group][theme].nil? then + guidance_array[guidance_group][theme] = [] + end + if !guidance_array[guidance_group][theme].include?(guidance) then + guidance_array[guidance_group][theme].push(guidance) + end + end return guidance_array - end - - ## - # finds the specified warning for the plan's project's organisation - # - # @param option_id [Integer] the id to find the OptionWarning associated - # @return [OptionWarning] the desired OptionWarning - def warning(option_id) - if project.organisation.nil? - return nil - else - return project.organisation.warning(option_id) - end - end + end ## # determines if the plan is editable by the specified user - # NOTE: This should be renamed to editable_by? # # @param user_id [Integer] the id for a user # @return [Boolean] true if user can edit the plan - def editable_by(user_id) - return project.editable_by(user_id) + def editable_by?(user_id) + user_id = user_id.id if user_id.is_a?(User) + role = roles.where(user_id: user_id).first + return role.present? && role.editor? end ## # determines if the plan is readable by the specified user - # NOTE: This shoudl be renamed to readable_by? + # TODO: introduce explicit readable rather than implicit + # currently role with no flags = readable # # @param user_id [Integer] the id for a user # @return [Boolean] true if the user can read the plan - def readable_by(user_id) - if project.nil? - return false - else - return project.readable_by(user_id) - end + def readable_by?(user_id) + user_id = user_id.id if user_id.is_a?(User) + role = roles.where(user_id: user_id).first + return role.present? end ## # determines if the plan is administerable by the specified user - # NOTE: This should be renamed to administerable_by? # # @param user_id [Integer] the id for the user # @return [Boolean] true if the user can administer the plan - def administerable_by(user_id) - return project.readable_by(user_id) + def administerable_by?(user_id) + user_id = user_id.id if user_id.is_a?(User) + role = roles.where(user_id: user_id).first + return role.present? && role.administrator? end ## # defines and returns the status of the plan # status consists of a hash of the num_questions, num_answers, sections, questions, and spaced used. - # For each section, it contains theid's of each of the questions + # For each section, it contains the id's of each of the questions # for each question, it contains the answer_id, answer_created_by, answer_text, answer_options_id, aand answered_by # # @return [Status] - def status - status = { - "num_questions" => 0, - "num_answers" => 0, - "sections" => {}, - "questions" => {}, - "space_used" => 0 # percentage of available space in pdf used - } - space_used = height_of_text(self.project.title, 2, 2) + def status + status = { + "num_questions" => 0, + "num_answers" => 0, + "sections" => {}, + "questions" => {}, + "space_used" => 0 # percentage of available space in pdf used + } - sections.each do |s| - space_used += height_of_text(s.title, 1, 1) - section_questions = 0 - section_answers = 0 - status["sections"][s.id] = {} - status["sections"][s.id]["questions"] = Array.new - s.questions.each do |q| - status["num_questions"] += 1 - section_questions += 1 - status["sections"][s.id]["questions"] << q.id - status["questions"][q.id] = {} - answer = answer(q.id, false) + space_used = height_of_text(self.title, 2, 2) - space_used += height_of_text(q.text) unless q.text == s.title - space_used += height_of_text(answer.try(:text) || I18n.t('helpers.plan.export.pdf.question_not_answered')) + section_ids = sections.map {|s| s.id} - if ! answer.nil? then - status["questions"][q.id] = { - "answer_id" => answer.id, - "answer_created_at" => answer.created_at.to_i, - "answer_text" => answer.text, - "answer_option_ids" => answer.option_ids, - "answered_by" => answer.user.name - } - q_format = q.question_format - status["num_answers"] += 1 if (q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") || - q_format.title == I18n.t("helpers.radio_buttons") || q_format.title == I18n.t("helpers.dropdown")) || answer.text.present? - section_answers += 1 - #TODO: include selected options in space estimate - else - status["questions"][q.id] = { - "answer_id" => nil, - "answer_created_at" => nil, - "answer_text" => nil, - "answer_option_ids" => nil, - "answered_by" => nil - } - end - status["sections"][s.id]["num_questions"] = section_questions - status["sections"][s.id]["num_answers"] = section_answers - end - end + # we retrieve this is 2 joins: + # 1. sections and questions + # 2. questions and answers + # why? because Rails 4 doesn't have any sensible left outer join. + # when we change to RAILS 5 it is meant to have so this can be fixed then - status['space_used'] = estimate_space_used(space_used) - return status - end + records = Section.joins(questions: :question_format) + .select('sections.id as sectionid, + sections.title as stitle, + questions.id as questionid, + questions.text as questiontext, + question_formats.title as qformat') + .where("sections.id in (?) ", section_ids) + .to_a + + # extract question ids to get answers + question_ids = records.map {|r| r.questionid}.uniq + status["num_questions"] = question_ids.count + + arecords = Question.joins(answers: :user) + .select('questions.id as questionid, + answers.id as answerid, + answers.plan_id as plan_id, + answers.text as answertext, + answers.updated_at as updated, + users.email as username') + .where("questions.id in (?) and answers.plan_id = ?",question_ids, self.id) + .to_a + + # we want answerids to extract options later + answer_ids = arecords.map {|r| r.answerid}.uniq + status["num_answers"] = answer_ids.count + + # create map from questionid to answer structure + qa_map = {} + arecords.each do |rec| + qa_map[rec.questionid] = { + plan: rec.plan_id, + id: rec.answerid, + text: rec.answertext, + updated: rec.updated, + user: rec.username + } + end + # build main status structure + records.each do |rec| + sid = rec.sectionid + stitle = rec.stitle + qid = rec.questionid + qtext = rec.questiontext + format = rec.qformat + + answer = nil + if qa_map.has_key?(qid) + answer = qa_map[qid] + end + + aid = answer.nil? ? nil : answer[:id] + atext = answer.nil? ? nil : answer[:text] + updated = answer.nil? ? nil : answer[:updated] + uname = answer.nil? ? nil : answer[:user] + + space_used += height_of_text(stitle, 1, 1) + + shash = status["sections"] + if !shash.has_key?(sid) + shash[sid] = {} + shash[sid]["num_questions"] = 0 + shash[sid]["num_answers"] = 0 + shash[sid]["questions"] = Array.new + end + + shash[sid]["questions"] << qid + shash[sid]["num_questions"] += 1 + + space_used += height_of_text(qtext) unless qtext == stitle + if atext.present? + space_used += height_of_text(atext) + else + space_used += height_of_text(_('Question not answered.')) + end + + if answer.present? then + shash[sid]["num_answers"] += 1 + end + + status["questions"][qid] = { + "format" => format, + "answer_id" => aid, + "answer_updated_at" => updated.to_i, + "answer_text" => atext, + "answered_by" => uname + } + + end + + records = Answer.joins(:question_options).select('answers.id as answerid, question_options.id as optid').where(id: answer_ids).to_a + opt_hash = {} + records.each do |rec| + aid = rec.answerid + optid = rec.optid + if !opt_hash.has_key?(aid) + opt_hash[aid] = Array.new + end + opt_hash[aid] << optid + end + + status["questions"].each_key do |questionid| + answerid = status["questions"][questionid]["answer_id"] + status["questions"][questionid]["answer_option_ids"] = opt_hash[answerid] + end + + status['space_used'] = estimate_space_used(space_used) + + return status + end + +# TODO: Guessing this isn't in use since it still refers to Project and Version +=begin ## # defines and returns the details for the plan # details consists of a hash of: project_title, phase_title, and for each section, # section: title, question text for each question, answer type and answer value # # @return [Details] - def details - details = { - "project_title" => project.title, - "phase_title" => version.phase.title, - "sections" => {} - } - sections.sort_by(&:"number").each do |s| - details["sections"][s.number] = {} - details["sections"][s.number]["title"] = s.title - details["sections"][s.number]["questions"] = {} - s.questions.order("number").each do |q| - details["sections"][s.number]["questions"][q.number] = {} - details["sections"][s.number]["questions"][q.number]["question_text"] = q.text - answer = answer(q.id, false) - if ! answer.nil? then + def details + details = { + "project_title" => project.title, + "phase_title" => version.phase.title, + "sections" => {} + } + sections.sort_by(&:"number").each do |s| + details["sections"][s.number] = {} + details["sections"][s.number]["title"] = s.title + details["sections"][s.number]["questions"] = {} + s.questions.order("number").each do |q| + details["sections"][s.number]["questions"][q.number] = {} + details["sections"][s.number]["questions"][q.number]["question_text"] = q.text + answer = answer(q.id, false) + if ! answer.nil? then q_format = q.question_format - if (q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || + if (q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown")) then - details["sections"][s.number]["questions"][q.number]["selections"] = {} - answer.options.each do |o| - details["sections"][s.number]["questions"][q.number]["selections"][o.number] = o.text - end - end - details["sections"][s.number]["questions"][q.number]["answer_text"] = answer.text - end - end - end - return details - end + details["sections"][s.number]["questions"][q.number]["selections"] = {} + answer.options.each do |o| + details["sections"][s.number]["questions"][q.number]["selections"][o.number] = o.text + end + end + details["sections"][s.number]["questions"][q.number]["answer_text"] = answer.text + end + end + end + return details + end +=end +# TODO: commenting this old lock stuff out since PlanSection is gone and we wanted to get rid of it +=begin ## # determines wether or not a specified section of a plan is locked to a specified user and returns a status hash # # @param section_id [Integer] the setion to determine if locked # @param user_id [Integer] the user to determine if locked for # @return [Hash{String => Hash{String => Boolean, nil, String, Integer}}] - def locked(section_id, user_id) - plan_section = plan_sections.where("section_id = ? AND user_id != ? AND release_time > ?", section_id, user_id, Time.now).last - if plan_section.nil? then - status = { - "locked" => false, - "locked_by" => nil, - "timestamp" => nil, - "id" => nil - } - else - status = { - "locked" => true, - "locked_by" => plan_section.user.name, - "timestamp" => plan_section.updated_at, - "id" => plan_section.id - } - end - end + def locked(section_id, user_id) + plan_section = plan_sections.where("section_id = ? AND user_id != ? AND release_time > ?", section_id, user_id, Time.now).last + if plan_section.nil? then + status = { + "locked" => false, + "locked_by" => nil, + "timestamp" => nil, + "id" => nil + } + else + status = { + "locked" => true, + "locked_by" => plan_section.user.name, + "timestamp" => plan_section.updated_at, + "id" => plan_section.id + } + end + end ## # for each section, lock the section with the given user_id # # @param user_id [Integer] the id for the user who can use the sections - def lock_all_sections(user_id) - sections.each do |s| - lock_section(s.id, user_id, 1800) - end - end + def lock_all_sections(user_id) + sections.each do |s| + lock_section(s.id, user_id, 1800) + end + end ## # for each section, unlock the section # # @param user_id [Integer] the id for the user to unlock the sections for - def unlock_all_sections(user_id) - plan_sections.where(:user_id => user_id).order("created_at DESC").each do |lock| - lock.delete - end - end + def unlock_all_sections(user_id) + plan_sections.where(:user_id => user_id).order("created_at DESC").each do |lock| + lock.delete + end + end ## # for each section, unlock the section # Not sure how this is different from unlock_all_sections # # @param user_id [Integer] - def delete_recent_locks(user_id) - plan_sections.where(:user_id => user_id).each do |lock| - lock.delete - end - end + def delete_recent_locks(user_id) + plan_sections.where(:user_id => user_id).each do |lock| + lock.delete + end + end ## # Locks the specified section to only be used by the specified user, for the number of secconds specified @@ -385,23 +535,23 @@ # @param user_id [Integer] the id of the user who can use the section # @param release_time [Integer] the number of secconds the section will be locked for, defaults to 60 # @return [Boolean] wether or not the section was locked - def lock_section(section_id, user_id, release_time = 60) - status = locked(section_id, user_id) - if ! status["locked"] then - plan_section = PlanSection.new - plan_section.plan_id = id - plan_section.section_id = section_id - plan_section.release_time = Time.now + release_time.seconds - plan_section.user_id = user_id - plan_section.save - elsif status["current_user"] then - plan_section = PlanSection.find(status["id"]) - plan_section.release_time = Time.now + release_time.seconds - plan_section.save - else - return false - end - end + def lock_section(section_id, user_id, release_time = 60) + status = locked(section_id, user_id) + if ! status["locked"] then + plan_section = PlanSection.new + plan_section.plan_id = id + plan_section.section_id = section_id + plan_section.release_time = Time.now + release_time.seconds + plan_section.user_id = user_id + plan_section.save + elsif status["current_user"] then + plan_section = PlanSection.find(status["id"]) + plan_section.release_time = Time.now + release_time.seconds + plan_section.save + else + return false + end + end ## # unlocks the specified section for the specified user @@ -409,65 +559,521 @@ # @param section_id [Integer] the id for the section to be unlocked # @param user_id [Integer] the id for the user for whom the section was previously locked # @return [Boolean] wether or not the lock was removed - def unlock_section(section_id, user_id) - plan_sections.where(:section_id => section_id, :user_id => user_id).order("created_at DESC").each do |lock| - lock.delete - end - end + def unlock_section(section_id, user_id) + plan_sections.where(:section_id => section_id, :user_id => user_id).order("created_at DESC").each do |lock| + lock.delete + end + end +=end +# TODO: Commenting out because this method appears below as well so this one is overwritten +=begin ## # returns the time of either the latest answer to any question, or the latest update to the model # # @return [DateTime] the time at which the plan was last changed - def latest_update - if answers.any? then - last_answered = answers.order("updated_at DESC").first.updated_at - if last_answered > updated_at then - return last_answered - else - return updated_at - end - else - return updated_at - end - end + def latest_update + if answers.any? then + last_answered = answers.order("updated_at DESC").first.updated_at + if last_answered > updated_at then + return last_answered + else + return updated_at + end + else + return updated_at + end + end +=end +# TODO: Guessing this isn't in use since it still refers to Project and Version +=begin ## # returns an array of hashes. Each hash contains the question's id, the answer_id, # the answer_text, the answer_timestamp, and the answer_options # # @param section_id [Integer] the section to find answers of # @return [Array nil,String,Integer,DateTime}] - def section_answers(section_id) - section = Section.find(section_id) - section_questions = Array.new - counter = 0 - section.questions.each do |q| - section_questions[counter] = {} - section_questions[counter]["id"] = q.id - #section_questions[counter]["multiple_choice"] = q.multiple_choice - q_answer = answer(q.id, false) - if q_answer.nil? then - section_questions[counter]["answer_id"] = nil - if q.suggested_answers.find_by_organisation_id(project.organisation_id).nil? then - section_questions[counter]["answer_text"] = "" - else - section_questions[counter]["answer_text"] = q.default_value - end - section_questions[counter]["answer_timestamp"] = nil - section_questions[counter]["answer_options"] = Array.new - else - section_questions[counter]["answer_id"] = q_answer.id - section_questions[counter]["answer_text"] = q_answer.text - section_questions[counter]["answer_timestamp"] = q_answer.created_at - section_questions[counter]["answer_options"] = q_answer.options.pluck(:id) - end - counter = counter + 1 - end - return section_questions - end + def section_answers(section_id) + section = Section.find(section_id) + section_questions = Array.new + counter = 0 + section.questions.each do |q| + section_questions[counter] = {} + section_questions[counter]["id"] = q.id + #section_questions[counter]["multiple_choice"] = q.multiple_choice + q_answer = answer(q.id, false) + if q_answer.nil? then + section_questions[counter]["answer_id"] = nil + if q.suggested_answers.find_by_organisation_id(project.organisation_id).nil? then + section_questions[counter]["answer_text"] = "" + else + section_questions[counter]["answer_text"] = q.default_value + end + section_questions[counter]["answer_timestamp"] = nil + section_questions[counter]["answer_options"] = Array.new + else + section_questions[counter]["answer_id"] = q_answer.id + section_questions[counter]["answer_text"] = q_answer.text + section_questions[counter]["answer_timestamp"] = q_answer.created_at + section_questions[counter]["answer_options"] = q_answer.options.pluck(:id) + end + counter = counter + 1 + end + return section_questions + end +=end -private + + ## + # assigns the passed user_id to the creater_role for the project + # gives the user rights to read, edit, administrate, and defines them as creator + # + # @param user_id [Integer] the user to be given priveleges' id + def assign_creator(user_id) + user_id = user_id.id if user_id.is_a?(User) + add_user(user_id, true, true, true) + end + + + +# TODO: commenting these out because they are overriden by private methods below, so this +# is unreachable +=begin + ## + # Based on the height of the text gathered so far and the available vertical + # space of the pdf, estimate a percentage of how much space has been used. + # This is highly dependent on the layout in the pdf. A more accurate approach + # would be to render the pdf and check how much space had been used, but that + # could be very slow. + # NOTE: This is only an estimate, rounded up to the nearest 5%; it is intended + # for guidance when editing plan data, not to be 100% accurate. + # + # @param used_height [Integer] an estimate of the height used so far + # @return [Integer] the estimate of space used of an A4 portrain + def estimate_space_used(used_height) + @formatting ||= self.settings(:export).formatting + + return 0 unless @formatting[:font_size] > 0 + + margin_height = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i + page_height = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait + available_height = page_height * self.template.settings(:export).max_pages + + percentage = (used_height / available_height) * 100 + (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five + end + + ## + # Take a guess at the vertical height (in mm) of the given text based on the + # font-size and left/right margins stored in the plan's settings. + # This assumes a fixed-width for each glyph, which is obviously + # incorrect for the font-face choices available; the idea is that + # they'll hopefully average out to that in the long-run. + # Allows for hinting different font sizes (offset from base via font_size_inc) + # and vertical margins (i.e. for heading text) + # + # @param text [String] the text to estimate size of + # @param font_size_inc [Integer] the size of the font of the text, defaults to 0 + # @param vertical_margin [Integer] the top margin above the text, defaults to 0 + def height_of_text(text, font_size_inc = 0, vertical_margin = 0) + @formatting ||= self.settings(:export).formatting + @margin_width ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i + @base_font_size ||= @formatting[:font_size] + + return 0 unless @base_font_size > 0 + + font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc) + font_width = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height + leading = font_height / 2 + + chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait + num_lines = (text.length / chars_in_line).ceil + + (num_lines * font_height) + vertical_margin + leading + end +=end + +# TODO: What are these used for? Should just be using self.org and self.org.funder? +=begin + ## + # sets a new funder for the project + # defaults to the first dmptemplate if the current template is nill and the funder has more than one dmptemplate + # + # @param new_funder_id [Integer] the id for a new funder + # @return [Organisation] the new funder + def funder_id=(new_funder_id) + if new_funder_id != "" then + new_funder = Org.find(new_funder_id); + if new_funder.templates.count >= 1 && self.template.nil? then + self.template = new_funder.templates.first + end + end + end +=end + + ## + # returns the funder id for the plan + # + # @return [Integer, nil] the id for the funder + def funder_id + if self.template.nil? then + return nil + end + return self.template.org + end + + ## + # returns the funder organisation for the project or nil if none is specified + # + # @return [Organisation, nil] the funder for project, or nil if none exists + def funder + template = self.template + if template.nil? then + return nil + end + + if template.customization_of + return template.customization_of.org + else + return template.org + end + end + +=begin + ## + # returns the name of the funder for the project + # + # @return [String] the name fo the funder for the project + def funder_name + if self.funder.nil? + return read_attribute(:funder_name) + else + return self.funder.name + end + end + + ## + # defines a new funder_name for the project. + # + # @param new_funder_name [String] the string name of the new funder + # @return [Integer, nil] the org_id of the new funder + def funder_name=(new_funder_name) + write_attribute(:funder_name, new_funder_name) + org_table = Org.arel_table + existing_org = Org.where(org_table[:name].matches(new_funder_name)) + if existing_org.nil? + existing_org = Org.where(org_table[:abbreviation].matches(new_funder_name)) + end + unless existing_org.empty? + self.funder_id=existing_org.id + end + end + + ## + # sets a new institution_id if there is no current organisation + # + # @param new_institution_id [Integer] the id for the new institution + # @return [Integer, Bool] false if an organisation exists, or the id of the set org if a new organisation is set + def institution_id=(new_institution_id) + if organisation.nil? then + self.organisation_id = new_institution_id + end + end + + ## + # returns the organisation which is root over the owning organisation + # + # @return [Integer, nil] the organisation_id or nil + def institution_id +# if organisation.nil? +# return nil +# else +# return organisation.root.id +# end + return template.org.id + end + + ## + # defines a new organisation_id for the project + # but is confusingly labled unit_id + # + # @param new_unit_id [Integer] + # @return [Integer, Boolean] the new organisation ID or false if no unit_id was passed + def unit_id=(new_unit_id) + unless new_unit_id.nil? ||new_unit_id == "" + self.organisation_id = new_unit_id + end + end + + ## + # returns the organisation_id or nil + # again seems redundant + # + # @return [nil, Integer] nil if no organisation, or the id if there is an organisation specified + def unit_id + if organisation.nil? || organisation.parent_id.nil? + return nil + else + return organisation_id + end + end +=end + + ## + # assigns the passed user_id as an editor for the project + # gives the user rights to read and edit + # + # @param user_id [Integer] the user to be given priveleges' id + def assign_editor(user_id) + add_user(user_id, true) + end + + ## + # assigns the passed user_id as a reader for the project + # gives the user rights to read + # + # @param user_id [Integer] the user to be given priveleges' id + def assign_reader(user_id) + add_user(user_id) + end + + ## + # assigns the passed user_id as an administrator for the project + # gives the user rights to read, adit, and administrate the project + # + # @param user_id [Integer] the user to be given priveleges' id + def assign_administrator(user_id) + add_user(user_id, true, true) + end + +# TODO: ProjectGroup doesn't exist anymore so commenting these out +=begin + ## + # returns the projects which the user can atleast read + # + # @param user_id [Integer] the user to lookup projects for + # @return [Array] list of all projects the user can atleast read + def self.projects_for_user(user_id) + projects = Array.new + groups = ProjectGroup.where("user_id = ?", user_id) + unless groups.nil? then + groups.each do |group| + unless group.project.nil? then + projects << group.project + end + end + end + return projects + end + + ## + # whether or not the specified user_id created this project + # should be renamed to created_by? + # + # @param user_id [Integer] the user to check the priveleges of + # @return [Boolean] true if the user created the project + def created_by(user_id) + user = project_groups.find_by_user_id(user_id) + if (! user.nil?) && user.project_creator then + return true + else + return false + end + end +=end + + ## + # the datetime for the latest update of this plan + # + # @return [DateTime] the time of latest update + def latest_update + latest_update = updated_at + phases.each do |phase| + if phase.updated_at > latest_update then + latest_update = phase.updated_at + end + end + return latest_update + end + + # Getters to match 'My plans' columns + + ## + # the title of the project + # + # @return [String] the title of the project + def name + self.title + end + + ## + # the owner of the project + # + # @return [User] the creater of the project + def owner + self.roles.each do |role| + if role.creator? + return role.user + end + end + return nil + end + + ## + # the time the project was last updated, formatted as a date + # + # @return [Date] last update as a date + def last_edited + self.latest_update.to_date + end + +# TODO: These next 2 reference defunct models so commenting out +=begin + ## + # whether or not the plan is shared with anybody + # + # @return [Boolean] true if the project has been shared + def shared? + self.project_groups.count > 1 + end + + alias_method :shared, :shared? + + ## + # the organisation who owns the project + # + # @return [Dmptemplate,Organisation,String] the template, it's owner, or it's owner's abreviation + def template_owner + self.dmptemplate.try(:organisation).try(:abbreviation) + end +=end + + # Returns the number of answered questions from the entire plan + def num_answered_questions + n = 0 + self.sections.each do |s| + n+= s.num_answered_questions(self.id) + end + return n + end + + # Returns a section given its id or nil if does not exist for the current plan + def get_section(section_id) + self.sections.find { |s| s.id == section_id } + end + + # Returns the number of questions for a plan. Note, this method becomes useful + # for when sections and their questions are eager loaded so that avoids SQL queries. + def num_questions + n = 0 + self.sections.each do |s| + n+= s.questions.size() + end + return n + end + # the following two methods are for eager loading. One gets used for the plan/show + # page and the oter for the plan/edit. The difference is just that one pulls in more than + # the other. + # TODO: revisit this and work out for sure that maintaining the difference is worthwhile. + # it may not be. Also make sure nether is doing more thanit needs to. + # + def self.eager_load(id) + Plan.includes( + [{template: [ + {phases: {sections: {questions: :answers}}}, + {customizations: :org} + ]}, + {plans_guidance_groups: {guidance_group: :guidances}} + ]).find(id) + end + + def self.eager_load2(id) + Plan.includes( + [{template: [ + {phases: {sections: {questions: [{answers: :notes}, :annotations, :question_format, :themes]}}}, + {customizations: :org}, + :org + ]}, + {plans_guidance_groups: {guidance_group: {guidances: :themes}}}, + {questions: :themes} + ]).find(id) + end + + + + private + + + ## + # adds a user to the project + # if no flags are specified, the user is given read privleges + # + # @param user_id [Integer] the user to be given privleges + # @param is_editor [Boolean] whether or not the user can edit the project + # @param is_administrator [Boolean] whether or not the user can administrate the project + # @param is_creator [Boolean] wheter or not the user created the project + # @return [Array] + # + # TODO: change this to specifying uniqueness of user/plan association and handle + # that way + # + def add_user(user_id, is_editor = false, is_administrator = false, is_creator = false) + Role.where(plan_id: self.id, user_id: user_id).each do |r| + r.destroy + end + + role = Role.new + role.user_id = user_id + role.plan_id = id + + # if you get assigned a role you can comment + role.commenter= true + + # the rest of the roles are inclusing so creator => administrator => editor + if is_creator + role.creator = true + role.administrator = true + role.editor = true + end + + if is_administrator + role.administrator = true + role.editor = true + end + + if is_editor + role.editor = true + end + + role.save + + # This is necessary because we're creating the associated record but not assigning it + # to roles. Auto-saving like this may be confusing when coding upstream in a controller, + # view or api. Should probably change this to: + # self.roles << role + # and then let the save be called manually via: + # plan.save! + #self.reload + end + + ## + # creates a plan for each phase in the dmptemplate associated with this project + # unless the phase is unpublished, it creates a new plan, and a new version of the plan and adds them to the project's plans + # + # @return [Array] + def create_plans + dmptemplate.phases.each do |phase| + latest_published_version = phase.latest_published_version + unless latest_published_version.nil? + new_plan = Plan.new + new_plan.version = latest_published_version + plans << new_plan + end + end + end + + ## # Based on the height of the text gathered so far and the available vertical @@ -522,4 +1128,14 @@ (num_lines * font_height) + vertical_margin + leading end + # Initialize the title and dirty flags for new templates + # -------------------------------------------------------- + def set_creation_defaults + # Only run this before_validation because rails fires this before save/create + if self.id.nil? + self.title = "My plan (#{self.template.title})" if self.title.nil? && !self.template.nil? + self.visibility = 3 + end + end + end diff --git a/app/models/plan_section.rb b/app/models/plan_section.rb deleted file mode 100644 index 6a92a74..0000000 --- a/app/models/plan_section.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PlanSection < ActiveRecord::Base - attr_accessible :plan_id, :release_time, :section_id, :user_id, :as => [:default, :admin] - - #associations between tables - belongs_to :section - belongs_to :plan - belongs_to :user - -end diff --git a/app/models/project.rb b/app/models/project.rb deleted file mode 100644 index f205429..0000000 --- a/app/models/project.rb +++ /dev/null @@ -1,359 +0,0 @@ -class Project < ActiveRecord::Base - include GlobalHelpers - - extend FriendlyId - - attr_accessible :dmptemplate_id, :title, :organisation_id, :unit_id, :guidance_group_ids, - :project_group_ids, :funder_id, :institution_id, :grant_number, :identifier, - :description, :principal_investigator, :principal_investigator_identifier, - :data_contact, :funder_name, :as => [:default, :admin] - - #associations between tables - belongs_to :dmptemplate - belongs_to :organisation - has_many :plans - has_many :project_groups, :dependent => :destroy - has_and_belongs_to_many :guidance_groups, join_table: "project_guidance" - - friendly_id :title, use: [:slugged, :history, :finders] - - ## - # returns the title of the project - # - # @return [String] the project's title - def to_s - "#{title}" - end - - after_create :create_plans - - ## - # sets a new funder for the project - # defaults to the first dmptemplate if the current template is nill and the funder has more than one dmptemplate - # - # @param new_funder_id [Integer] the id for a new funder - # @return [Organisation] the new funder - def funder_id=(new_funder_id) - if new_funder_id != "" then - new_funder = Organisation.find(new_funder_id); - if new_funder.dmptemplates.count >= 1 && self.dmptemplate.nil? then - self.dmptemplate = new_funder.dmptemplates.first - end - end - end - - ## - # returns the funder id for the project - # - # @return [Integer, nil] the id for the funder - def funder_id - if self.dmptemplate.nil? then - return nil - end - template_org = self.dmptemplate.organisation - if template_org.organisation_type.name == constant("organisation_types.funder").downcase - return template_org.id - else - return nil - end - end - - ## - # returns the funder organisation for the project or nil if none is specified - # - # @return [Organisation, nil] the funder for project, or nil if none exists - def funder - if self.dmptemplate.nil? then - return nil - end - template_org = self.dmptemplate.organisation - if template_org.organisation_type.name == constant("organisation_types.funder").downcase - return template_org - else - return nil - end - end - - ## - # returns the name of the funder for the project - # - # @return [String] the name fo the funder for the project - def funder_name - if self.funder.nil? - return read_attribute(:funder_name) - else - return self.funder.name - end - end - - ## - # defines a new funder_name for the project. - # - # @param new_funder_name [String] the string name of the new funder - # @return [Integer, nil] the org_id of the new funder - def funder_name=(new_funder_name) - write_attribute(:funder_name, new_funder_name) - org_table = Organisation.arel_table - existing_org = Organisation.where(org_table[:name].matches(new_funder_name)) - if existing_org.nil? - existing_org = Organisation.where(org_table[:abbreviation].matches(new_funder_name)) - end - unless existing_org.empty? - self.funder_id=existing_org.id - end - end - - ## - # sets a new institution_id if there is no current organisation - # - # @param new_institution_id [Integer] the id for the new institution - # @return [Integer, Bool] false if an organisation exists, or the id of the set org if a new organisation is set - def institution_id=(new_institution_id) - if organisation.nil? then - self.organisation_id = new_institution_id - end - end - - ## - # returns the organisation which is root over the owning organisation - # - # @return [Integer, nil] the organisation_id or nil - def institution_id - if organisation.nil? - return nil - else - return organisation.root.id - end - end - - ## - # defines a new organisation_id for the project - # but is confusingly labled unit_id - # - # @param new_unit_id [Integer] - # @return [Integer, Boolean] the new organisation ID or false if no unit_id was passed - def unit_id=(new_unit_id) - unless new_unit_id.nil? ||new_unit_id == "" - self.organisation_id = new_unit_id - end - end - - ## - # returns the organisation_id or nil - # again seems redundant - # - # @return [nil, Integer] nil if no organisation, or the id if there is an organisation specified - def unit_id - if organisation.nil? || organisation.parent_id.nil? - return nil - else - return organisation_id - end - end - - ## - # assigns the passed user_id to the creater_role for the project - # gives the user rights to read, edit, administrate, and defines them as creator - # - # @param user_id [Integer] the user to be given priveleges' id - def assign_creator(user_id) - add_user(user_id, true, true, true) - end - - ## - # assigns the passed user_id as an editor for the project - # gives the user rights to read and edit - # - # @param user_id [Integer] the user to be given priveleges' id - def assign_editor(user_id) - add_user(user_id, true) - end - - ## - # assigns the passed user_id as a reader for the project - # gives the user rights to read - # - # @param user_id [Integer] the user to be given priveleges' id - def assign_reader(user_id) - add_user(user_id) - end - - ## - # assigns the passed user_id as an administrator for the project - # gives the user rights to read, adit, and administrate the project - # - # @param user_id [Integer] the user to be given priveleges' id - def assign_administrator(user_id) - add_user(user_id, true, true) - end - - ## - # whether or not the current plan is administrable by the user - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can administer project, false otherwise - def administerable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) && user.project_administrator then - return true - else - return false - end - end - - ## - # whether or not the current plan is editable by the user - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can edit project, false otherwise - def editable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) && user.project_editor then - return true - else - return false - end - end - - ## - # whether or not the current plan is readable by the user - # should be renamed to readable_by? - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can read project, false otherwise - def readable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) then - return true - else - return false - end - end - - ## - # returns the projects which the user can atleast read - # - # @param user_id [Integer] the user to lookup projects for - # @return [Array] list of all projects the user can atleast read - def self.projects_for_user(user_id) - projects = Array.new - groups = ProjectGroup.where("user_id = ?", user_id) - unless groups.nil? then - groups.each do |group| - unless group.project.nil? then - projects << group.project - end - end - end - return projects - end - - ## - # whether or not the specified user_id created this project - # should be renamed to created_by? - # - # @param user_id [Integer] the user to check the priveleges of - # @return [Boolean] true if the user created the project - def created_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) && user.project_creator then - return true - else - return false - end - end - - ## - # the datetime for the latest update of this project, or any plan it owns - # - # @return [DateTime] the time of latest update - def latest_update - latest_update = updated_at - plans.each do |plan| - if plan.latest_update > latest_update then - latest_update = plan.latest_update - end - end - return latest_update - end - - # Getters to match 'My plans' columns - - ## - # the title of the project - # - # @return [String] the title of the project - def name - self.title - end - - ## - # the owner of the project - # - # @return [User] the creater of the project - def owner - self.project_groups.find_by_project_creator(true).try(:user) - end - - ## - # the time the project was last updated, formatted as a date - # - # @return [Date] last update as a date - def last_edited - self.latest_update.to_date - end - - ## - # whether or not the plan is shared with anybody - # - # @return [Boolean] true if the project has been shared - def shared? - self.project_groups.count > 1 - end - - alias_method :shared, :shared? - - ## - # the organisation who owns the project - # - # @return [Dmptemplate,Organisation,String] the template, it's owner, or it's owner's abreviation - def template_owner - self.dmptemplate.try(:organisation).try(:abbreviation) - end - - private - - ## - # adds a user to the project - # if no flags are specified, the user is given read privleges - # - # @param user_id [Integer] the user to be given privleges - # @param is_editor [Boolean] whether or not the user can edit the project - # @param is_administrator [Boolean] whether or not the user can administrate the project - # @param is_creator [Boolean] wheter or not the user created the project - # @return [Array] - def add_user(user_id, is_editor = false, is_administrator = false, is_creator = false) - group = ProjectGroup.new - group.user_id = user_id - group.project_creator = is_creator - group.project_editor = is_editor - group.project_administrator = is_administrator - project_groups << group - end - - ## - # creates a plan for each phase in the dmptemplate associated with this project - # unless the phase is unpublished, it creates a new plan, and a new version of the plan and adds them to the project's plans - # - # @return [Array] - def create_plans - dmptemplate.phases.each do |phase| - latest_published_version = phase.latest_published_version - unless latest_published_version.nil? - new_plan = Plan.new - new_plan.version = latest_published_version - plans << new_plan - end - end - end -end diff --git a/app/models/project_group.rb b/app/models/project_group.rb deleted file mode 100644 index 05a4c1e..0000000 --- a/app/models/project_group.rb +++ /dev/null @@ -1,66 +0,0 @@ -class ProjectGroup < ActiveRecord::Base - - #associations between tables - belongs_to :project - belongs_to :user - - attr_accessible :project_creator, :project_editor, :project_administrator, :project_id, :user_id, :email, :access_level, :as => [:default, :admin] - - ## - # returns the user's email unless it is nil - # - # @return [Boolean, String] false if no email exists, the email otherwise - def email - unless user.nil? - return user.email - end - end - - ## - # define a new user for the project group by email - # - # @param new_email [String] the email of the new user for the project group - # @return [User] the new user - def email=(new_email) - unless User.find_by(email: email).nil? then - user = User.find_by(email: email) - end - end - - ## - # return the access level for the current project group - # 3 if the user is an administrator - # 2 if the user is an editor - # 1 if the user can only read - # - # @return [Integer] - def access_level - if project_administrator then - return 3 - elsif project_editor then - return 2 - else - return 1 - end - end - - ## - # define a new access level for the current project group - # if >=3, the user is a project administrator - # if >=2, the user is an editor - # - # @param new_access_level [Integer] the access level to give the user - def access_level=(new_access_level) - new_access_level = new_access_level.to_i - if new_access_level >= 3 then - project_administrator = true - else - project_administrator = false - end - if new_access_level >= 2 then - project_editor = true - else - project_editor = false - end - end -end diff --git a/app/models/project_partner.rb b/app/models/project_partner.rb deleted file mode 100644 index 3c82e18..0000000 --- a/app/models/project_partner.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ProjectPartner < ActiveRecord::Base - attr_accessible :leader_org, :organisation_id, :project_id, :as => [:default, :admin] -end diff --git a/app/models/question.rb b/app/models/question.rb index aed95fb..0a3e947 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -1,26 +1,43 @@ class Question < ActiveRecord::Base - #associations between tables - has_many :answers, :dependent => :destroy - has_many :options, :dependent => :destroy - has_many :suggested_answers, :dependent => :destroy - has_many :guidances - has_many :comments - - has_and_belongs_to_many :themes, join_table: "questions_themes" - + ## + # Sort order: Number ASC + default_scope { order(number: :asc) } + ## + # Associations + has_many :answers, :dependent => :destroy + has_many :question_options, :dependent => :destroy, :inverse_of => :question # inverse_of needed for nester forms + has_many :annotations, :dependent => :destroy + has_and_belongs_to_many :themes, join_table: "questions_themes" belongs_to :section belongs_to :question_format + ## + # Nested Attributes + # TODO: evaluate if we need this accepts_nested_attributes_for :answers, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true -# accepts_nested_attributes_for :section -# accepts_nested_attributes_for :question_format - accepts_nested_attributes_for :options, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true - accepts_nested_attributes_for :suggested_answers, :allow_destroy => true + accepts_nested_attributes_for :question_options, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true + accepts_nested_attributes_for :annotations, :allow_destroy => true accepts_nested_attributes_for :themes - attr_accessible :default_value, :dependency_id, :dependency_text, :guidance,:number, :parent_id, :suggested_answer, :text, :section_id,:question_format_id,:options_attributes, :suggested_answers_attributes, :option_comment_display, :theme_ids, :as => [:default, :admin] + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :default_value, :dependency_id, :dependency_text, :guidance,:number, + :annotation, :text, :section_id, :question_format_id, + :question_options_attributes, :annotations_attributes, + :option_comment_display, :theme_ids, :section, :question_format, + :question_options, :annotations, :answers, :themes, + :modifiable, :option_comment_display, :as => [:default, :admin] + + validates :text, :section, :number, presence: {message: _("can't be blank")} + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + ## # returns the text from the question @@ -30,91 +47,83 @@ "#{text}" end - def select_text - cleantext = text.gsub(/<[^<]+>/, '') - if cleantext.length > 120 - cleantext = cleantext.slice(0,120) + + def option_based? + format = self.question_format + return format.option_based + end + + def plan_answers(plan_id) + return self.answers.to_a.select{|ans| ans.plan_id == plan_id} + end + + ## + # deep copy the given question and all it's associations + # + # @params [Question] question to be deep copied + # @return [Question] the saved, copied question + def self.deep_copy(question) + question_copy = question.dup + question_copy.save! + question.question_options.each do |question_option| + question_option_copy = QuestionOption.deep_copy(question_option) + question_option_copy.question_id = question_copy.id + question_option_copy.save! end - cleantext + question.annotations.each do |annotation| + annotation_copy = Annotation.deep_copy(annotation) + annotation_copy.question_id = question_copy.id + annotation_copy.save! + end + question.themes.each do |theme| + question_copy.themes << theme + end + return question_copy end - amoeba do - include_association :options - include_association :suggested_answers - clone [:themes] - end - - #def question_type? - # type_label = {} - # if self.is_text_field? - # type_label = 'Text field' - # elsif self.multiple_choice? - # type_label = 'Multiple choice' - # else - # type_label = 'Text area' - # end - # return type_label - #end - ## - # for each question theme, appends them separated by comas - # shouldnt have a ? after the method name + # guidance for org # - # @return [Hash{String=> String}] - def question_themes? - themes_label = {} - i = 1 - themes_quest = self.themes - - themes_quest.each do |tt| - themes_label = tt.title - - if themes_quest.count > i then - themes_label += ',' - i +=1 - end - end - - return themes_label - end - - ## - # guidance for question in the org admin - # - # @param question [Question] the question to find guidance for - # @param org_admin [Organisation] the organisation to find guidance for + # @param org [Org] the org to find guidance for # @return [Hash{String => String}] - def guidance_for_question(question, org_admin) - # pulls together guidance from various sources for question - guidances = {} - theme_ids = question.theme_ids - - GuidanceGroup.where("organisation_id = ?", org_admin.id).each do |group| - group.guidances.each do |g| - g.themes.where("id IN (?)", theme_ids).each do |gg| - guidances["#{group.name} " + I18n.t('admin.guidance_lowercase_on') + " #{gg.title}"] = g - end + def guidance_for_org(org) + # pulls together guidance from various sources for question + guidances = {} + theme_ids = themes.collect{|t| t.id} + if theme_ids.present? + GuidanceGroup.includes(guidances: :themes).where(org_id: org.id).each do |group| + group.guidances.each do |g| + g.themes.each do |theme| + if theme_ids.include? theme.id + guidances["#{group.name} " + _('guidance on') + " #{theme.title}"] = g end + end end - # Guidance link to directly to a question - question.guidances.each do |g_by_q| - g_by_q.guidance_groups.each do |group| - if group.organisation == org_admin - guidances["#{group.name} " + I18n.t('admin.guidance_lowercase')] = g_by_q - end - end - end + end + end + return guidances end ## - # get suggested answer belonging to the currents user for this question + # get example answer belonging to the currents user for this question # # @param org_id [Integer] the id for the organisation - # @return [String] the suggested_answer for this question for the specified organisation - def get_suggested_answer(org_id) - suggested_answer = suggested_answers.find_by_organisation_id(org_id) - return suggested_answer + # @return [String] the example answer for this question for the specified org + def get_example_answer(org_id) + example_answer = self.annotations.where(org_id: org_id).where(type: Annotation.types[:example_answer]).order(:created_at) + return example_answer.first end + ## + # get guidance belonging to the current user's org for this question(need org + # to distinguish customizations) + # + # @param org_id [Integer] the id for the organisation + # @return [String] the annotation guidance for this question for the specified org + def get_guidance_annotation(org_id) + guidance = self.annotations.where(org_id: org_id).where(type: Annotation.types[:guidance]) + return guidance.first + end + end diff --git a/app/models/question_format.rb b/app/models/question_format.rb index b8ede7c..b7d6afc 100644 --- a/app/models/question_format.rb +++ b/app/models/question_format.rb @@ -1,8 +1,31 @@ class QuestionFormat < ActiveRecord::Base - attr_accessible :title, :description, :as => [:default, :admin] - #associations between tables + ## + # Associations has_many :questions + + enum formattype: [ :textarea, :textfield, :radiobuttons, :checkbox, :dropdown, :multiselectbox, :date ] + attr_accessible :formattype + + validates :title, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :title, :description, :option_based, :questions, :as => [:default, :admin] + + # Retrieves the id for a given formattype passed + scope :id_for, -> (formattype) { where(formattype: formattype).pluck(:id).first } + + ## + # Define Bit Field Values so we can test a format without doing string comps + # Column type + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + ## # gives the title of the question_format # @@ -11,4 +34,4 @@ "#{title}" end -end \ No newline at end of file +end diff --git a/app/models/question_option.rb b/app/models/question_option.rb new file mode 100644 index 0000000..b0fec82 --- /dev/null +++ b/app/models/question_option.rb @@ -0,0 +1,26 @@ +class QuestionOption < ActiveRecord::Base + ## + # Associations + belongs_to :question + has_and_belongs_to_many :answers, join_table: :answers_question_options + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :text, :question_id, :is_default, :number, :question, + :as => [:default, :admin] + + validates :text, :question, :number, presence: {message: _("can't be blank")} + + scope :by_number, -> { order(:number) } + ## + # deep copy the given question_option and all it's associations + # + # @params [QuestionOption] question_option to be deep copied + # @return [QuestionOption] the saved, copied question_option + def self.deep_copy(question_option) + question_option_copy = question_option.dup + question_option_copy.save! + return question_option_copy + end +end diff --git a/app/models/region.rb b/app/models/region.rb index 8147fed..a7e366a 100644 --- a/app/models/region.rb +++ b/app/models/region.rb @@ -1,3 +1,8 @@ class Region < ActiveRecord::Base - + has_many :sub_regions, class_name: 'Region', foreign_key: 'super_region_id' + + belongs_to :super_region, class_name: 'Region' + + validates :name, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} + validates :abbreviation, uniqueness: {message: _("must be unique")}, allow_nil: true end \ No newline at end of file diff --git a/app/models/region_group.rb b/app/models/region_group.rb deleted file mode 100644 index 8f83a83..0000000 --- a/app/models/region_group.rb +++ /dev/null @@ -1,3 +0,0 @@ -class RegionGroup < ActiveRecord::Base - -end \ No newline at end of file diff --git a/app/models/role.rb b/app/models/role.rb index dbe0a80..a51177d 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,8 +1,59 @@ class Role < ActiveRecord::Base - has_and_belongs_to_many :users, :join_table => :users_roles + include FlagShihTzu + + ## + # Associationsrequire "role" - belongs_to :resource, :polymorphic => true - - attr_accessible :name, :role_in_plans, :resource_id, :resource_type, :as => [:default, :admin] - + belongs_to :user + belongs_to :plan + + ## + # Define Bit Field Values + # Column access + has_flags 1 => :creator, # 1 + 2 => :administrator, # 2 + 3 => :editor, # 4 + 4 => :commenter, # 8 + column: 'access' + + validates :user, :plan, :access, presence: {message: _("can't be blank")} + validates :access, numericality: {greater_than: 0, message: _("can't be less than zero")} + + ## + # return the access level for the current project group + # 3 if the user is an administrator + # 2 if the user is an editor + # 1 if the user can only read + # used to facilliatte formtastic + # + # @return [Integer] + def access_level + if self.administrator? + return 3 + elsif self.editor? + return 2 + elsif self.commenter? + return 1 + end + end + end + +# ----------------------------------------------------- +# Bitwise key +# ----------------------------------------------------- +# 01 - creator +# 02 - administrator +# 03 - creator + administrator +# 04 - editor +# 05 - creator + editor +# 06 - administraor + editor +# 07 - creator + editor + administrator +# 08 - commenter +# 09 - creator + commenter +# 10 - administrator + commenter +# 11 - creator + administrator + commenter +# 12 - editor + commenter +# 13 - creator + editor + commenter +# 14 - administrator + editor + commenter +# 15 - creator + administrator + editor + commenter \ No newline at end of file diff --git a/app/models/section.rb b/app/models/section.rb index fd1dcb7..4d4562b 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -1,16 +1,19 @@ class Section < ActiveRecord::Base - - #associations between tables - belongs_to :version + ## + # Associations + belongs_to :phase belongs_to :organisation has_many :questions, :dependent => :destroy - has_many :plan_sections, :dependent => :destroy #Link the data accepts_nested_attributes_for :questions, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true # accepts_nested_attributes_for :version - attr_accessible :organisation_id, :description, :number, :title, :version_id , :published, :questions_attributes, :as => [:default, :admin] + attr_accessible :phase_id, :description, :number, :title, :published, + :questions_attributes, :organisation, :phase, :modifiable, + :as => [:default, :admin] + + validates :phase, :title, :number, presence: {message: _("can't be blank")} ## # return the title of the section @@ -20,8 +23,28 @@ "#{title}" end - amoeba do - include_association :questions + # Returns the number of answered questions for a given plan id + def num_answered_questions(plan_id) + n = 0 + self.questions.each do |question| + n += question.plan_answers(plan_id).select{|answer| answer.is_valid?}.count + end + return n end + ## + # deep copy of the given section and all it's associations + # + # @params [Section] section to be deep copied + # @return [Section] the saved, copied section + def self.deep_copy(section) + section_copy = section.dup + section_copy.save! + section.questions.each do |question| + question_copy = Question.deep_copy(question) + question_copy.section_id = section_copy.id + question_copy.save! + end + return section_copy + end end diff --git a/app/models/settings/dmptemplate.rb b/app/models/settings/dmptemplate.rb deleted file mode 100644 index a5ce2de..0000000 --- a/app/models/settings/dmptemplate.rb +++ /dev/null @@ -1,93 +0,0 @@ -module Settings - class Dmptemplate < RailsSettings::SettingObject - - #attr_accessible :var, :target, :target_id, :target_type - - VALID_FONT_FACES = [ - 'Arial, Helvetica, Sans-Serif', - '"Times New Roman", Times, Serif' - ] - - VALID_FONT_SIZE_RANGE = (8..14) - VALID_MARGIN_RANGE = (5..25) - - VALID_ADMIN_FIELDS = ['project_name', 'project_identifier', 'grant_title', 'principal_investigator', - 'project_data_contact', 'project_description', 'funder', 'institution'] - - DEFAULT_SETTINGS = { - formatting: { - margin: { # in millimeters - top: 20, - bottom: 20, - left: 20, - right: 20 - }, - font_face: VALID_FONT_FACES.first, - font_size: 12 # pt - }, - max_pages: 3, - fields: { - admin: VALID_ADMIN_FIELDS, - questions: :all - }, - title: "" - } - - validate do - formatting = value['formatting'] - max_pages = value['max_pages'] - fields = value['fields'] - - if formatting.present? - errs = [] - default_formatting = DEFAULT_SETTINGS[:formatting] - - unless (default_formatting.keys - formatting.keys).empty? - errs << :missing_key - else - unless formatting[:margin].is_a?(Hash) - errs << :invalid_margin - else - errs << :negative_margin if formatting[:margin].any? {|k,v| v.to_i < 0 } - errs << :unknown_margin unless (formatting[:margin].keys - default_formatting[:margin].keys).empty? - errs << :invalid_margin unless formatting[:margin].all? {|k,v| VALID_MARGIN_RANGE.member?(v) } - end - - errs << :invalid_font_size unless VALID_FONT_SIZE_RANGE.member?(formatting[:font_size]) - errs << :invalid_font_face unless VALID_FONT_FACES.member?(formatting[:font_face]) - errs << :unknown_key unless (formatting.keys - default_formatting.keys).empty? - end - - errs.map do |key| - errors.add(:formatting, I18n.t("helpers.settings.plans.errors.#{key}")) - end - - end - - if max_pages.present? && (!max_pages.is_a?(Integer) || max_pages <= 0) - errors.add(:max_pages, I18n.t('helpers.settings.plans.errors.invalid_max_pages')) - end - end - - before_validation do - self.formatting[:font_size] = self.formatting[:font_size].to_i if self.formatting[:font_size].present? - unless self.formatting[:margin].nil? or (not self.formatting[:margin].is_a?(Hash)) - self.formatting[:margin].each do |key, val| - self.formatting[:margin][key] = val.to_i - end - end - - self.fields.each do |key, val| - if val.is_a?(Hash) - val = key == :questions ? val.keys.map {|k| k.to_s.to_i } : val.keys - end - - self.fields[key] = val - end - - # Save empty arrays if we don't have any fields for them - self.fields[:admin] ||= [] - self.fields[:questions] ||= [] - end - end -end diff --git a/app/models/settings/plan_list.rb b/app/models/settings/plan_list.rb deleted file mode 100644 index 17e93a9..0000000 --- a/app/models/settings/plan_list.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Settings - class PlanList < RailsSettings::SettingObject - - #attr_accessible :var, :target, :target_type, :target_id - - # TODO: can these be taken from somewhere else rather than hard-coded here? - DEFAULT_COLUMNS = ['name', 'owner', 'shared', 'last_edited'] - ALL_COLUMNS = DEFAULT_COLUMNS + ['template_owner', 'identifier', 'grant_number', - 'principal_investigator', 'data_contact', 'description'] - - validate do - cols = value["columns"] - - if cols.present? # columns can be empty, in which case they revert to defaults - errors.add(:columns, I18n.t("helpers.settings.projects.errors.no_name")) unless cols.member?("name") - errors.add(:columns, I18n.t("helpers.settings.projects.errors.duplicate")) unless cols.keys.uniq == cols.keys - errors.add(:columns, I18n.t("helpers.settings.projects.errors.unknown")) unless (cols.keys.uniq & ALL_COLUMNS) == cols.keys.uniq - end - end - end -end diff --git a/app/models/settings/template.rb b/app/models/settings/template.rb new file mode 100644 index 0000000..59ac3de --- /dev/null +++ b/app/models/settings/template.rb @@ -0,0 +1,107 @@ +module Settings + class Template < RailsSettings::SettingObject + + #attr_accessible :var, :target, :target_id, :target_type + + VALID_FONT_FACES = [ + 'Arial, Helvetica, Sans-Serif', + '"Times New Roman", Times, Serif' + ] + + VALID_FONT_SIZE_RANGE = (8..14) + VALID_MARGIN_RANGE = (5..25) + + VALID_ADMIN_FIELDS = ['project_name', 'project_identifier', 'grant_title', 'principal_investigator', + 'project_data_contact', 'project_description', 'funder', 'institution', 'orcid'] + + DEFAULT_SETTINGS = { + formatting: { + margin: { # in millimeters + top: 20, + bottom: 20, + left: 20, + right: 20 + }, + font_face: VALID_FONT_FACES.first, + font_size: 12 # pt + }, + max_pages: 3, + fields: { + admin: VALID_ADMIN_FIELDS, + questions: :all + }, + title: "" + } + + validate do + formatting = value['formatting'] + max_pages = value['max_pages'] + fields = value['fields'] + + if formatting.present? + errs = [] + default_formatting = DEFAULT_SETTINGS[:formatting] + + unless (default_formatting.keys - formatting.keys).empty? + errs << :missing_key + else + unless formatting[:margin].is_a?(Hash) + errs << :invalid_margin + else + errs << :negative_margin if formatting[:margin].any? {|k,v| v.to_i < 0 } + errs << :unknown_margin unless (formatting[:margin].keys - default_formatting[:margin].keys).empty? + errs << :invalid_margin unless formatting[:margin].all? {|k,v| VALID_MARGIN_RANGE.member?(v) } + end + + errs << :invalid_font_size unless VALID_FONT_SIZE_RANGE.member?(formatting[:font_size]) + errs << :invalid_font_face unless VALID_FONT_FACES.member?(formatting[:font_face]) + errs << :unknown_key unless (formatting.keys - default_formatting.keys).empty? + end + + errs.map do |key| + if key == :missing_key + errors.add(:formatting, _('A required setting has not been provided')) + elsif key == :invalid_margin + errors.add(:formatting, _('Margin value is invalid')) + elsif key == :negative_margin + errors.add(:formatting, _('Margin cannot be negative')) + elsif key == :unknown_margin + errors.add(:formatting, _("Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'")) + elsif key == :invalid_font_size + errors.add(:formatting, _('Invalid font size')) + elsif key == :invalid_font_face + errors.add(:formatting, _('Invalid font face')) + elsif key == :unknown_key + errors.add(:formatting, _('Unknown formatting setting')) + end + end + + end + + if max_pages.present? && (!max_pages.is_a?(Integer) || max_pages <= 0) + errors.add(:max_pages, _('Invalid maximum pages')) + end + end + + before_validation do + self.formatting[:font_size] = self.formatting[:font_size].to_i if self.formatting[:font_size].present? + unless self.formatting[:margin].nil? or (not self.formatting[:margin].is_a?(Hash)) + self.formatting[:margin].each do |key, val| + self.formatting[:margin][key] = val.to_i + end + end + + self.fields.each do |key, val| + if val.is_a?(Hash) + val = key == :questions ? val.keys.map {|k| k.to_s.to_i } : val.keys + end + + self.fields[key] = val + end + + # Save empty arrays if we don't have any fields for them + self.fields[:admin] ||= [] + self.fields[:questions] ||= [] + end + end +end diff --git a/app/models/suggested_answer.rb b/app/models/suggested_answer.rb deleted file mode 100644 index 3bbefa8..0000000 --- a/app/models/suggested_answer.rb +++ /dev/null @@ -1,18 +0,0 @@ -class SuggestedAnswer < ActiveRecord::Base - - belongs_to :organisation - belongs_to :question - -# accepts_nested_attributes_for :question - - attr_accessible :organisation_id, :question_id, :text, :is_example, :as => [:default, :admin] - - ## - # returns the text from the suggested_answer - # - # @return [String] the text from the suggested_answer - def to_s - "#{text}" - end - -end \ No newline at end of file diff --git a/app/models/template.rb b/app/models/template.rb new file mode 100644 index 0000000..b72d216 --- /dev/null +++ b/app/models/template.rb @@ -0,0 +1,159 @@ +class Template < ActiveRecord::Base + include GlobalHelpers + + before_validation :set_creation_defaults + scope :valid, -> {where(migrated: false)} + ## + # Associations + belongs_to :org + has_many :plans + has_many :phases, dependent: :destroy + has_many :sections, through: :phases + has_many :questions, through: :sections + + has_many :customizations, class_name: 'Template', foreign_key: 'dmptemplate_id' + belongs_to :dmptemplate, class_name: 'Template' + + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + attr_accessible :id, :org_id, :description, :published, :title, :locale, :customization_of, + :is_default, :guidance_group_ids, :org, :plans, :phases, :dmptemplate_id, + :migrated, :version, :visibility, :published, :as => [:default, :admin] + + # defines the export setting for a template object + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS + end + + validates :org, :title, :version, presence: {message: _("can't be blank")} + + # Retrieves the list of all dmptemplate_ids (template versioning families) for the specified Org + def self.dmptemplate_ids + Template.all.valid.distinct.pluck(:dmptemplate_id) + end + + # Retrieves the most recent version of the template for the specified Org and dmptemplate_id + def self.current(dmptemplate_id) + Template.where(dmptemplate_id: dmptemplate_id).order(version: :desc).valid.first + end + + # Retrieves the current published version of the template for the specified Org and dmptemplate_id + def self.live(dmptemplate_id) + Template.where(dmptemplate_id: dmptemplate_id, published: true).valid.first + end + + ## + # Retrieves the most current customization of the template for the + # specified org and dmptemplate_id + # returns nil if no customizations found + # + # @params [integer] dmptemplate_id of the original template + # @params [integer] org_id for the customizing organisation + # @return [nil, Template] the customized template or nil + def self.org_customizations(dmptemplate_id, org_id) + Template.where(customization_of: dmptemplate_id, org_id: org_id).order(version: :desc).valid.first + end + + ## + # deep copy the given template and all of it's associations + # + # @params [Template] template to be deep copied + # @return [Template] saved copied template + def self.deep_copy(template) + template_copy = template.dup + template_copy.save! + template.phases.each do |phase| + phase_copy = Phase.deep_copy(phase) + phase_copy.template_id = template_copy.id + phase_copy.save! + end + return template_copy + end + + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + + ## + # convert the given template to a hash and return with all it's associations + # to use, please pre-fetch org, phases, section, questions, annotations, + # question_options, question_formats, + # TODO: Themes & guidance? + # + # @return [hash] hash of template, phases, sections, questions, question_options, annotations + def to_hash + hash = {} + hash[:template] = {} + hash[:template][:data] = self + hash[:template][:org] = self.org + phases = {} + hash[:template][:phases] = phases + self.phases.each do |phase| + phases[phase.number] = {} + phases[phase.number][:data] = phase + phases[phase.number][:sections] = {} + phase.sections.each do |section| + phases[phase.number][:sections][section.number] = {} + phases[phase.number][:sections][section.number][:data] = section + phases[phase.number][:sections][section.number][:questions] = {} + section.questions.each do |question| + phases[phase.number][:sections][section.number][:questions][question.number] = {} + phases[phase.number][:sections][section.number][:questions][question.number][:data] = question + phases[phase.number][:sections][section.number][:questions][question.number][:annotations] = {} + question.annotations.each do |annotation| + phases[phase.number][:sections][section.number][:questions][question.number][:annotations][annotation.id] = {} + phases[phase.number][:sections][section.number][:questions][question.number][:annotations][annotation.id][:data] = annotation + end + phases[phase.number][:sections][section.number][:questions][question.number][:question_options] = {} + question.question_options.each do |question_option| + phases[phase.number][:sections][section.number][:questions][question.number][:question_options][:data] = question_option + phases[phase.number][:sections][section.number][:questions][question.number][:question_format] = question.question_format + end + end + end + end + return hash + end + +# TODO: Why are we passing in an org and template here? + ## + # Verify if a template has customisation by given organisation + # + # @param org_id [integer] the integer id for an organisation + # @param temp [dmptemplate] a template object + # @return [Boolean] true if temp has customisation by the given organisation + def has_customisations?(org_id, temp) + modifiable = true + phases.each do |phase| + modifiable = modifiable && phase.modifiable + end + return !modifiable + end + + # -------------------------------------------------------- + private + # Initialize the published and dirty flags for new templates + def set_creation_defaults + # Only run this before_validation because rails fires this before save/create + if self.id.nil? + self.published = false + self.migrated = false + self.dirty = false + self.visibility = 1 + self.is_default = false + self.version = 0 if self.version.nil? + + # Generate a unique identifier for the dmptemplate_id if necessary + if self.dmptemplate_id.nil? + self.dmptemplate_id = loop do + random = rand 2147483647 + break random unless Template.exists?(dmptemplate_id: random) + end + end + end + end + +end diff --git a/app/models/theme.rb b/app/models/theme.rb index 0b31f36..bd787f6 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -1,17 +1,26 @@ class Theme < ActiveRecord::Base - #associations between tables + ## + # Associations has_and_belongs_to_many :questions, join_table: "questions_themes" has_and_belongs_to_many :guidances, join_table: "themes_in_guidance" - -# accepts_nested_attributes_for :guidances -# accepts_nested_attributes_for :questions - + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :guidance_ids , :as => [:default, :admin] attr_accessible :question_ids, :as => [:default, :admin] attr_accessible :description, :title, :locale , :as => [:default, :admin] + + validates :title, presence: {message: _("can't be blank")} + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + + ## # returns the title of the theme # diff --git a/app/models/token_permission_type.rb b/app/models/token_permission_type.rb index 8d368b6..5770e6c 100644 --- a/app/models/token_permission_type.rb +++ b/app/models/token_permission_type.rb @@ -1,12 +1,26 @@ class TokenPermissionType < ActiveRecord::Base + ## + # Associations + #has_and_belongs_to_many :org_token_permissions, join_table: "org_token_permissions" +# has_and_belongs_to_many :organisations, join_table: 'org_token_permissions', unique: true + has_and_belongs_to_many :orgs, join_table: 'org_token_permissions', unique: true + ## + # Possibly needed for active_admin + # - relies on proetected_attributes gem as syntax depricated in rails 4.2 attr_accessible :token_type, :text_description, :as => [:default, :admin] - #associations between tables - #has_and_belongs_to_many :org_token_permissions, join_table: "org_token_permissions" - has_and_belongs_to_many :organisations, join_table: 'org_token_permissions' + ## + # Validators + validates :token_type, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} - validates :token_type, presence: true, uniqueness: true + ## + # Constant Token Permission Types + GUIDANCES = TokenPermissionType.where(token_type: 'guidances').first.freeze + PLANS = TokenPermissionType.where(token_type: 'plans').first.freeze + TEMPLATES = TokenPermissionType.where(token_type: 'templates').first.freeze + STATISTICS = TokenPermissionType.where(token_type: 'statistics').first.freeze + ## # returns the token_type of the token_permission_type diff --git a/app/models/user.rb b/app/models/user.rb index f6fbde2..c1350f6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,61 +1,78 @@ class User < ActiveRecord::Base include GlobalHelpers - # Include default devise modules. Others available are: - # :token_authenticatable, :confirmable, - # :lockable, :timeoutable and :omniauthable - devise :invitable, :database_authenticatable, :registerable, :recoverable, :rememberable, - :trackable, :validatable, :confirmable, :omniauthable, :omniauth_providers => [:shibboleth] + ## + # Devise + # Include default devise modules. Others available are: + # :token_authenticatable, :confirmable, + # :lockable, :timeoutable and :omniauthable + devise :invitable, :database_authenticatable, :registerable, :recoverable, + :rememberable, :trackable, :validatable, :omniauthable, + :omniauth_providers => [:shibboleth, :orcid] - #associations between tables - belongs_to :user_type - belongs_to :user_status - has_many :answers - has_many :user_org_roles - has_many :project_groups, :dependent => :destroy - has_many :user_role_types, through: :user_org_roles - belongs_to :language - - belongs_to :organisation - - has_many :projects, through: :project_groups do - def filter(query) - return self unless query.present? - - t = self.arel_table - q = "%#{query}%" - - conditions = t[:title].matches(q) - - columns = %i( - grant_number identifier description principal_investigator data_contact - ) - columns = ['grant_number', 'identifier', 'description', 'principal_investigator', 'data_contact'] - - columns.each {|col| conditions = conditions.or(t[col].matches(q)) } - - self.where(conditions) - end + ## + # Associations + has_and_belongs_to_many :perms, join_table: :users_perms + belongs_to :language + belongs_to :org + has_many :answers + has_many :notes + has_many :exported_plans + has_many :roles, dependent: :destroy + has_many :plans, through: :roles do + def filter(query) + return self unless query.present? + t = self.arel_table + q = "%#{query}%" + conditions = t[:title].matches(q) + columns = %i( + grant_number identifier description principal_investigator data_contact + ) + columns = ['grant_number', 'identifier', 'description', 'principal_investigator', 'data_contact'] + columns.each {|col| conditions = conditions.or(t[col].matches(q)) } + self.where(conditions) end + end + + has_many :user_identifiers + has_many :identifier_schemes, through: :user_identifiers - has_and_belongs_to_many :roles, :join_table => :users_roles + ## + # Possibly needed for active_admin + # -relies on protected_attributes gem as syntax depricated in rails 4.2 + #accepts_nested_attributes_for :roles + #attr_accessible :password_confirmation, :encrypted_password, :remember_me, + # :id, :email, :firstname, :last_login,:login_count, :orcid_id, + # :password, :shibboleth_id, :user_status_id, :surname, + # :user_type_id, :org_id, :skip_invitation, :other_organisation, + # :accept_terms, :role_ids, :dmponline3, :api_token, + # :organisation, :language, :language_id, :org, :perms, + # :confirmed_at, :org_id - has_many :plan_sections + validates :email, email: true, allow_nil: true, uniqueness: {message: _("must be unique")} - accepts_nested_attributes_for :roles - attr_accessible :password_confirmation, :encrypted_password, :remember_me, :id, :email, - :firstname, :last_login,:login_count, :orcid_id, :password, :shibboleth_id, - :user_status_id, :surname, :user_type_id, :organisation_id, :skip_invitation, - :other_organisation, :accept_terms, :role_ids, :dmponline3, :api_token, - :organisation, :language, :language_id + ## + # Scopes + default_scope { includes(:org, :perms, :plans) } - validates :email, email: true, allow_nil: true, uniqueness: true - # FIXME: The duplication in the block is to set defaults. It might be better if - # they could be set in Settings::PlanList itself, if possible. - has_settings :plan_list, class_name: 'Settings::PlanList' do |s| - s.key :plan_list, defaults: { columns: Settings::PlanList::DEFAULT_COLUMNS } + + # EVALUATE CLASS AND INSTANCE METHODS BELOW + # + # What do they do? do they do it efficiently, and do we need them? + + # Determines the locale set for the user or the organisation he/she belongs + # @return String or nil + def get_locale + if !self.language.nil? + return self.language.abbreviation + elsif !self.org.nil? + return self.org.get_locale + else + return nil end + end + ## # gives either the name of the user, or the email if name unspecified @@ -63,7 +80,7 @@ # @param user_email [Boolean] defaults to true, allows the use of email if there is no firstname or surname # @return [String] the email or the firstname and surname of the user def name(use_email = true) - if ((firstname.nil? && surname.nil?) || (firstname.strip == "" && surname.strip == "")) && use_email then + if (firstname.blank? && surname.blank?) || use_email then return email else name = "#{firstname} #{surname}" @@ -72,19 +89,31 @@ end ## + # Returns the user's identifier for the specified scheme name + # + # @param the identifier scheme name (e.g. ORCID) + # @return [UserIdentifier] the user's identifier for that scheme + def identifier_for(scheme) + user_identifiers.where(identifier_scheme: scheme).first + end + +# TODO: Check the logic here. Its deleting the permissions if the user does not have permission +# to change orgs and either the incoming or existing org is nil. +# We should also NOT be auto-saving here!!! + ## # sets a new organisation id for the user - # if the user has any roles such as org_admin or admin, those are removed + # if the user has any perms such as org_admin or admin, those are removed # if the user had an api_token, that is removed # # @param new_organisation_id [Integer] the id for an organisation # @return [String] the empty string as a causality of setting api_token - def organisation_id=(new_organisation_id) - unless self.can_change_org? || new_organisation_id.nil? || self.organisation.nil? + def org_id=(new_org_id) + unless self.can_change_org? || new_org_id.nil? || self.org.nil? || (new_org_id.to_s == self.org.id.to_s) # rip all permissions from the user - self.roles.delete_all + self.perms.delete_all end # set the user's new organisation - super(new_organisation_id) + super(new_org_id) self.save! # rip api permissions from the user self.remove_token! @@ -94,10 +123,10 @@ # sets a new organisation for the user # # @param new_organisation [Organisation] the new organisation for the user - def organisation=(new_organisation) - organisation_id = new_organisation.id unless new_organisation.nil? + def organisation=(new_org) + org_id = new_org.id unless new_org.nil? end - + ## # checks if the user is a super admin # if the user has any privelege which requires them to see the super admin page @@ -105,7 +134,7 @@ # # @return [Boolean] true if the user is an admin def can_super_admin? - return self.can_add_orgs? || self.can_grant_api_to_orgs? || can_change_org? + return self.can_add_orgs? || self.can_grant_api_to_orgs? || self.can_change_org? end ## @@ -115,7 +144,8 @@ # # @return [Boolean] true if the user is an organisation admin def can_org_admin? - return self.can_grant_permissions? || self.can_modify_guidance? || self.can_modify_templates? || self.can_modify_org_details? + return self.can_grant_permissions? || self.can_modify_guidance? || + self.can_modify_templates? || self.can_modify_org_details? end ## @@ -123,7 +153,7 @@ # # @return [Boolean] true if the user can add new organisations def can_add_orgs? - roles.include? Role.find_by(name: constant("user_role_types.add_organisations")) + perms.include? Perm.add_orgs end ## @@ -131,7 +161,7 @@ # # @return [Boolean] true if the user can change their organisation affiliations def can_change_org? - roles.include? Role.find_by(name: constant("user_role_types.change_org_affiliation")) + perms.include? Perm.change_affiliation end ## @@ -139,7 +169,7 @@ # # @return [Boolean] true if the user can grant their permissions to others def can_grant_permissions? - roles.include? Role.find_by(name: constant("user_role_types.grant_permissions")) + perms.include? Perm.grant_permissions end ## @@ -147,7 +177,7 @@ # # @return [Boolean] true if the user can modify organisation templates def can_modify_templates? - roles.include? Role.find_by(name: constant("user_role_types.modify_templates")) + self.perms.include? Perm.modify_templates end ## @@ -155,7 +185,7 @@ # # @return [Boolean] true if the user can modify organistion guidance def can_modify_guidance? - roles.include? Role.find_by(name: constant("user_role_types.modify_guidance")) + perms.include? Perm.modify_guidance end ## @@ -163,7 +193,7 @@ # # @return [Boolean] true if the user can use the api def can_use_api? - roles.include? Role.find_by(name: constant("user_role_types.use_api")) + perms.include? Perm.use_api end ## @@ -171,15 +201,7 @@ # # @return [Boolean] true if the user can modify the org's details def can_modify_org_details? - roles.include? Role.find_by(name: constant("user_role_types.change_org_details")) - end - - ## - # checks if the user can grant the api to organisations - # - # @return [Boolean] true if the user can grant api permissions to organisations - def can_grant_api_to_orgs? - roles.include? Role.find_by(name: constant('user_role_types.grant_api_to_orgs')) + perms.include? Perm.change_org_details end @@ -188,18 +210,20 @@ # # @return [Boolean] true if the user can grant api permissions to organisations def can_grant_api_to_orgs? - roles.include? Role.find_by(name: constant('user_role_types.grant_api_to_orgs')) + perms.include? Perm.grant_api end ## # checks what type the user's organisation is # # @return [String] the organisation type +=begin def org_type - org_type = organisation.organisation_type.name + org_type = org.organisation_type return org_type end - +=end + ## # removes the api_token from the user # modifies the user model @@ -221,53 +245,37 @@ end self.save! # send an email to the user to notify them of their new api token - UserMailer.api_token_granted_notification(self) + #UserMailer.api_token_granted_notification(self) end end ## - # updates the user permissions to the new system. - # the old system only had admin and org-admin roles, which loosely map to the - # new permissions system. - def self.update_user_permissions - admin = Role.find_by(name: 'admin') - org_admin = Role.find_by(name: 'org_admin') - add_orgs = Role.find_by(name: 'add_organisations') - change_org_affiliation = Role.find_by(name: 'change_org_affiliation') - grant_api_to_orgs = Role.find_by(name: 'grant_api_to_orgs') - grant_permissions = Role.find_by(name: 'grant_permissions') - modify_templates = Role.find_by(name: 'modify_templates') - modify_guidance = Role.find_by(name: 'modify_guidance') - change_org_details = Role.find_by(name: 'change_org_details') - User.includes(:roles).all.each do |user| - if user.roles.include? admin - #add admin roles - user.roles << add_orgs unless user.roles.include? add_orgs - user.roles << change_org_affiliation unless user.roles.include? change_org_affiliation - user.roles << grant_api_to_orgs unless user.roles.include? grant_api_to_orgs - user.roles << grant_permissions unless user.roles.include? grant_permissions - user.roles.delete(admin) - user.save! - end - if user.roles.include? org_admin - #add org-admin roles - user.roles << grant_permissions unless user.roles.include? grant_permissions - user.roles << modify_templates unless user.roles.include? modify_templates - user.roles << modify_guidance unless user.roles.include? modify_guidance - user.roles << change_org_details unless user.roles.include? change_org_details - user.roles.delete(org_admin) - # save the user - user.save! - end + # Load the user based on the scheme and id provided by the Omniauth call + # -------------------------------------------------------------- + def self.from_omniauth(auth) + scheme = IdentifierScheme.find_by(name: auth.provider.downcase) + + if scheme.nil? + throw Exception.new('Unknown OAuth provider: ' + auth.provider) + else + joins(:user_identifiers).where('user_identifiers.identifier': auth.uid, + 'user_identifiers.identifier_scheme_id': scheme.id).first end end + ## + # Override devise_invitable email title + # -------------------------------------------------------------- + def deliver_invitation(options = {}) + super(options.merge(subject: _('A Data Management Plan in %{application_name} has been shared with you') % {application_name: Rails.configuration.branding[:application][:name]})) + end - +# TODO: Remove this, its never called. # this generates a reset password link for a given user # which can then be sent to them with the appropriate host # prepended. +=begin def reset_password_link raw, enc = Devise.token_generator.generate(self.class, :reset_password_token) self.reset_password_token = enc @@ -276,6 +284,6 @@ edit_user_password_path + '?reset_password_token=' + raw end - - +=end + end diff --git a/app/models/user_identifier.rb b/app/models/user_identifier.rb new file mode 100644 index 0000000..840e394 --- /dev/null +++ b/app/models/user_identifier.rb @@ -0,0 +1,9 @@ +class UserIdentifier < ActiveRecord::Base + belongs_to :user + belongs_to :identifier_scheme + + # Should only be able to have one identifier per scheme! + validates_uniqueness_of :identifier_scheme, scope: :user + + validates :identifier, :user, :identifier_scheme, presence: {message: _("can't be blank")} +end \ No newline at end of file diff --git a/app/models/user_org_role.rb b/app/models/user_org_role.rb deleted file mode 100644 index 10fca3c..0000000 --- a/app/models/user_org_role.rb +++ /dev/null @@ -1,9 +0,0 @@ -class UserOrgRole < ActiveRecord::Base - attr_accessible :organisation_id, :user_id, :user_role_type_id, :as => [:default, :admin] - - #associations between tables - belongs_to :user - belongs_to :organisation - belongs_to :user_role_type - -end diff --git a/app/models/user_role_type.rb b/app/models/user_role_type.rb deleted file mode 100644 index e012aca..0000000 --- a/app/models/user_role_type.rb +++ /dev/null @@ -1,7 +0,0 @@ -class UserRoleType < ActiveRecord::Base - - #associations between tables - has_many :user_org_roles - - attr_accessible :description, :name, :as => [:default, :admin] -end diff --git a/app/models/user_status.rb b/app/models/user_status.rb deleted file mode 100644 index a8c4dcd..0000000 --- a/app/models/user_status.rb +++ /dev/null @@ -1,6 +0,0 @@ -class UserStatus < ActiveRecord::Base - attr_accessible :description, :name, :as => [:default, :admin] - - #associations between tables - has_many :users -end diff --git a/app/models/user_type.rb b/app/models/user_type.rb deleted file mode 100644 index 8ceb4d4..0000000 --- a/app/models/user_type.rb +++ /dev/null @@ -1,6 +0,0 @@ -class UserType < ActiveRecord::Base - attr_accessible :description, :name, :as => [:default, :admin] - - #associations between tables - has_many :users -end diff --git a/app/models/version.rb b/app/models/version.rb deleted file mode 100644 index db03966..0000000 --- a/app/models/version.rb +++ /dev/null @@ -1,41 +0,0 @@ -class Version < ActiveRecord::Base - - #associations between tables - belongs_to :phase - - has_many :sections, :dependent => :destroy - has_many :questions, :through => :sections, :dependent => :destroy - has_many :plans - - #Link the data -# accepts_nested_attributes_for :phase - accepts_nested_attributes_for :sections, :allow_destroy => true - - attr_accessible :id, :description, :number, :published, :title, :phase_id, - :sections_attributes, :as => [:default, :admin] - - ## - # returns the title of the version - # - # @return [String] the title of the version - def to_s - "#{title}" - end - - - ## - # returns all sections where the org_id is the same as this version's phase's org_id - # - # @return [Array
    ] - def global_sections - sections.where("organisation_id = ? ", phase.dmptemplate.organisation_id).load - end - - amoeba do - include_association :sections - include_association :questions - set :published => 'false' - prepend :title => "Copy of " - end - -end diff --git a/app/policies/annotation_policy.rb b/app/policies/annotation_policy.rb new file mode 100644 index 0000000..a426546 --- /dev/null +++ b/app/policies/annotation_policy.rb @@ -0,0 +1,29 @@ +class AnnotationPolicy < ApplicationPolicy + attr_reader :user, :annotation + + def initialize(user, annotation) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @annotation = annotation + end + + ## + # Users can modify annotations if: + # - They can modify templates + # - The template which they are modifying belongs to their orggi + ## + + def admin_create? + # here we pass through a question instead of an annotation object + user.can_modify_templates? && (annotation.section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (annotation.question.section.phase.template.org_id == user.org_id) && annotation.org_id == user.org_id + end + + def admin_destroy? + user.can_modify_templates? && (annotation.question.section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/answer_policy.rb b/app/policies/answer_policy.rb index 61f6989..1e9502c 100644 --- a/app/policies/answer_policy.rb +++ b/app/policies/answer_policy.rb @@ -8,8 +8,10 @@ @answer = answer end - def create? - @answer.plan.editable_by(@user.id) + def update? + # TODO: Remove the owner check after the Roles have been updated + # is the plan editable by the user or the user is the owner of the plan + @answer.plan.editable_by?(@user.id) || @user == @answer.plan.owner end end \ No newline at end of file diff --git a/app/policies/api/v0/guidance_group_policy.rb b/app/policies/api/v0/guidance_group_policy.rb new file mode 100644 index 0000000..1ea52f4 --- /dev/null +++ b/app/policies/api/v0/guidance_group_policy.rb @@ -0,0 +1,29 @@ +module Api + module V0 + class GuidanceGroupPolicy < ApplicationPolicy + attr_reader :user, :guidance_group + + def initialize(user, guidance_group) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::GUIDANCES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @guidance_group = guidance_group + end + + ## + # is the plan editable by the user + def show? + GuidanceGroup.can_view?(@user, @guidance_group) + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/guidance_policy.rb b/app/policies/api/v0/guidance_policy.rb new file mode 100644 index 0000000..fd17c4e --- /dev/null +++ b/app/policies/api/v0/guidance_policy.rb @@ -0,0 +1,29 @@ +module Api + module V0 + class GuidancePolicy < ApplicationPolicy + attr_reader :user + attr_reader :guidance + + def initialize(user, guidance) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::GUIDANCES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @guidance = guidance + end + + ## + # is the plan editable by the user + def show? + Guidance.can_view(@user, @guidance.id) + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/plans_policy.rb b/app/policies/api/v0/plans_policy.rb new file mode 100644 index 0000000..6d0ab77 --- /dev/null +++ b/app/policies/api/v0/plans_policy.rb @@ -0,0 +1,23 @@ +module Api + module V0 + class PlansPolicy < ApplicationPolicy + attr_reader :user + attr_reader :template + + def initialize(user, template) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::PLANS + raise Pundit::NotAuthorizedError, _("must have access to plans api") + end + @user = user + @template = template + end + + ## + # users can create a plan if their template exists + def create? + @template.present? + end + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/statistics_policy.rb b/app/policies/api/v0/statistics_policy.rb new file mode 100644 index 0000000..155a3da --- /dev/null +++ b/app/policies/api/v0/statistics_policy.rb @@ -0,0 +1,41 @@ +module Api + module V0 + class StatisticsPolicy < ApplicationPolicy + attr_reader :user + + def initialize(user, statistic) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::STATISTICS + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @statistic = statistic + end + + ## + # always allowed to see how many users joined your org within a date range + def users_joined? + true + end + + ## + # need to check if your org owns this template + def using_template? + @statistic.org_id == @user.org_id + end + + ## + # always allowed to get plans by template + def plans_by_template? + true + end + + ## + # always allowed to get plans + def plans? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/template_policy.rb b/app/policies/api/v0/template_policy.rb new file mode 100644 index 0000000..7ec770b --- /dev/null +++ b/app/policies/api/v0/template_policy.rb @@ -0,0 +1,23 @@ +module Api + module V0 + class TemplatePolicy < ApplicationPolicy + attr_reader :user, :template + + def initialize(user, template) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::TEMPLATES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @template = template + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index de9b7ba..c0664f3 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -13,7 +13,7 @@ end def show? - scope.where(:id => record.id).exists? + scope.where(id: record.id).exists? end def create? diff --git a/app/policies/comment_policy.rb b/app/policies/comment_policy.rb deleted file mode 100644 index 570c0a1..0000000 --- a/app/policies/comment_policy.rb +++ /dev/null @@ -1,23 +0,0 @@ -class CommentPolicy < ApplicationPolicy - attr_reader :user - attr_reader :comment - - def initialize(user, comment) - raise Pundit::NotAuthorizedError, "must be logged in" unless user - @user = user - @comment = comment - end - - def create? - Plan.find(@comment.plan_id).readable_by(@user.id) - end - - def update? - Plan.find(@comment.plan_id).readable_by(@user.id) - end - - def archive? - Plan.find(@comment.plan_id).readable_by(@user.id) - end - -end \ No newline at end of file diff --git a/app/policies/dmptemplate_policy.rb b/app/policies/dmptemplate_policy.rb deleted file mode 100644 index c2dbe91..0000000 --- a/app/policies/dmptemplate_policy.rb +++ /dev/null @@ -1,124 +0,0 @@ -class DmptemplatePolicy < ApplicationPolicy - attr_reader :user, :dmptemplate - - def initialize(user, dmptemplate) - raise Pundit::NotAuthorizedError, "must be logged in" unless user - @user = user - @dmptemplate = dmptemplate - end - - def admin_index? - user.can_modify_templates? - end - - def admin_template? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_update? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_new? - user.can_modify_templates? - end - - def admin_create? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroy? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_phase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_previewphase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_addphase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_createphase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updatephase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroyphase? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updateversion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_cloneversion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroyversion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_createsection? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updatesection? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroysection? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_createquestion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updatequestion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroyquestion? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_createsuggestedanswer? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updatesuggestedanswer? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroysuggestedanswer? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_createguidance? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_updateguidance? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - def admin_destroyguidance? - user.can_modify_templates? #&& (dmptemplate.organisation_id == user.organisation_id) - end - - class Scope < Scope - def resolve - scope.where(organisation_id: user.organisation_id) - end - end - -end \ No newline at end of file diff --git a/app/policies/guidance_group_policy.rb b/app/policies/guidance_group_policy.rb index 422ea26..bb514c3 100644 --- a/app/policies/guidance_group_policy.rb +++ b/app/policies/guidance_group_policy.rb @@ -8,19 +8,19 @@ end def admin_show? - user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + user.can_modify_guidance? && (guidance_group.org_id == user.org_id) end def admin_edit? - user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + user.can_modify_guidance? && (guidance_group.org_id == user.org_id) end def admin_update? - user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + user.can_modify_guidance? && (guidance_group.org_id == user.org_id) end def admin_update_publish? - user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + user.can_modify_guidance? && (guidance_group.org_id == user.org_id) end def admin_new? @@ -32,12 +32,12 @@ end def admin_destroy? - user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + user.can_modify_guidance? && (guidance_group.org_id == user.org_id) end class Scope < Scope def resolve - scope.where(organisation_id: user.organisation_id) + scope.where(org_id: user.org_id) end end diff --git a/app/policies/guidance_policy.rb b/app/policies/guidance_policy.rb index e527c4a..725326c 100644 --- a/app/policies/guidance_policy.rb +++ b/app/policies/guidance_policy.rb @@ -8,15 +8,15 @@ end def admin_show? - user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.org_id) end def admin_edit? - user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.org_id) end def admin_update? - user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.org_id) end def admin_index? @@ -32,7 +32,7 @@ end def admin_destroy? - user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.org_id) end def update_phases? @@ -53,7 +53,7 @@ class Scope < Scope def resolve - scope = Guidance.by_organisation(user.organisation_id) + scope = Guidance.includes(:guidance_group, :themes).by_org(user.org_id) end end end \ No newline at end of file diff --git a/app/policies/note_policy.rb b/app/policies/note_policy.rb new file mode 100644 index 0000000..88a9e11 --- /dev/null +++ b/app/policies/note_policy.rb @@ -0,0 +1,23 @@ +class NotePolicy < ApplicationPolicy + attr_reader :user + attr_reader :note + + def initialize(user, note) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @note = note + end + + def create? + @note.answer.plan.readable_by?(@user.id) + end + + def update? + Plan.find(@note.answer.plan_id).readable_by?(@user.id) + end + + def archive? + Plan.find(@note.answer.plan_id).readable_by?(@user.id) + end + +end diff --git a/app/policies/org_policy.rb b/app/policies/org_policy.rb new file mode 100644 index 0000000..311d389 --- /dev/null +++ b/app/policies/org_policy.rb @@ -0,0 +1,34 @@ +class OrgPolicy < ApplicationPolicy + attr_reader :user, :org + + def initialize(user, org) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @org = org + end + + def admin_show? + user.can_modify_org_details? && (user.org_id == org.id) + end + + def admin_edit? + user.can_modify_org_details? && (user.org_id == org.id) + end + + def admin_update? + user.can_modify_org_details? && (user.org_id == org.id) + end + + def parent? + true + end + + def children? + true + end + + def templates? + true + end + +end \ No newline at end of file diff --git a/app/policies/organisation_policy.rb b/app/policies/organisation_policy.rb deleted file mode 100644 index 8fb3bb2..0000000 --- a/app/policies/organisation_policy.rb +++ /dev/null @@ -1,34 +0,0 @@ -class OrganisationPolicy < ApplicationPolicy - attr_reader :user, :organisation - - def initialize(user, organisation) - raise Pundit::NotAuthorizedError, "must be logged in" unless user - @user = user - @organisation = organisation - end - - def admin_show? - user.can_modify_org_details? && (user.organisation.id == organisation.id) - end - - def admin_edit? - user.can_modify_org_details? && (user.organisation.id == organisation.id) - end - - def admin_update? - user.can_modify_org_details? && (user.organisation.id == organisation.id) - end - - def parent? - true - end - - def children? - true - end - - def templates? - true - end - -end \ No newline at end of file diff --git a/app/policies/phase_policy.rb b/app/policies/phase_policy.rb new file mode 100644 index 0000000..caa0e3c --- /dev/null +++ b/app/policies/phase_policy.rb @@ -0,0 +1,40 @@ +class PhasePolicy < ApplicationPolicy + attr_reader :user, :phase + + def initialize(user, phase) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @phase = phase + end + + ## + # Org-admin side + # Users can modify phases if: + # - They can modify templates + # - The template which they are modifying belongs to their org + + def admin_show? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_preview? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_add? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_create? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/plan_policy.rb b/app/policies/plan_policy.rb index 2d4d08a..aa99a2b 100644 --- a/app/policies/plan_policy.rb +++ b/app/policies/plan_policy.rb @@ -8,51 +8,75 @@ @plan = plan end + def show? + @plan.readable_by?(@user.id) + end + def edit? - @plan.editable_by(@user.id) + @plan.readable_by?(@user.id) + end + + def update_guidance_choices? + @plan.editable_by?(@user.id) + end + + def share? + @plan.readable_by?(@user.id) end def export? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) + end + + def show_export? + @plan.readable_by?(@user.id) end def update? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end + def destroy? + @plan.editable_by?(@user.id) + end + def status? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) + end + + def possible_templates? + @plan.id.nil? end +# TODO: These routes are no lonmger used +=begin def section_answers? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def locked? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def delete_recent_locks? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def unlock_all_sections? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def lock_section? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def unlock_section? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end +=end def answer? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end - def warning? - @plan.readable_by(@user.id) - end -end \ No newline at end of file +end diff --git a/app/policies/project_group_policy.rb b/app/policies/project_group_policy.rb deleted file mode 100644 index 595687e..0000000 --- a/app/policies/project_group_policy.rb +++ /dev/null @@ -1,22 +0,0 @@ -class ProjectGroupPolicy < ApplicationPolicy - attr_reader :user - attr_reader :project_group - - def initialize(user, project_group) - raise Pundit::NotAuthorizedError, "must be logged in" unless user - @user = user - @project_group = project_group - end - - def create? - @project_group.project.administerable_by(@user.id) - end - - def update? - @project_group.project.administerable_by(@user.id) - end - - def destroy? - @project_group.project.administerable_by(@user.id) - end -end \ No newline at end of file diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 60c76fd..9ca5bcc 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -39,4 +39,5 @@ def possible_guidance? true end + end \ No newline at end of file diff --git a/app/policies/question_policy.rb b/app/policies/question_policy.rb new file mode 100644 index 0000000..5ea487c --- /dev/null +++ b/app/policies/question_policy.rb @@ -0,0 +1,28 @@ +class QuestionPolicy < ApplicationPolicy + attr_reader :user, :question + + def initialize(user, question) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @question = question + end + + ## + # Users can modify questions if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_create? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/role_policy.rb b/app/policies/role_policy.rb new file mode 100644 index 0000000..cf2b691 --- /dev/null +++ b/app/policies/role_policy.rb @@ -0,0 +1,22 @@ +class RolePolicy < ApplicationPolicy + attr_reader :user + attr_reader :role + + def initialize(user, role) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @role = role + end + + def create? + @role.plan.administerable_by?(@user.id) + end + + def update? + @role.plan.administerable_by?(@user.id) + end + + def destroy? + @role.plan.administerable_by?(@user.id) + end +end \ No newline at end of file diff --git a/app/policies/section_policy.rb b/app/policies/section_policy.rb new file mode 100644 index 0000000..6effdbe --- /dev/null +++ b/app/policies/section_policy.rb @@ -0,0 +1,28 @@ +class SectionPolicy < ApplicationPolicy + attr_reader :user, :section + + def initialize(user, section) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @section = section + end + + ## + # Users can modify sections if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_create? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/template_policy.rb b/app/policies/template_policy.rb new file mode 100644 index 0000000..754e622 --- /dev/null +++ b/app/policies/template_policy.rb @@ -0,0 +1,67 @@ +class TemplatePolicy < ApplicationPolicy + attr_reader :user, :template + + def initialize(user, template) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @template = template + end + + ## + # Users can modify templates if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_index? + user.can_modify_templates? + end + + def admin_template? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_customize? + user.can_modify_templates? + end + + def admin_publish? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_unpublish? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_new? + user.can_modify_templates? + end + + def admin_create? + user.can_modify_templates? && (template.org_id.nil? || (template.org_id == user.org_id)) + end + + def admin_destroy? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_template_history? + user.can_modify_templates? && (template.org_id == user.org_id) + end + + def admin_transfer_customization? + user.can_modify_templates? + end + + + class Scope < Scope + def resolve + scope.where(org_id: user.org_id) + end + end + +end \ No newline at end of file diff --git a/app/policies/token_permission_type_policy.rb b/app/policies/token_permission_type_policy.rb index fb4699e..ee4a947 100644 --- a/app/policies/token_permission_type_policy.rb +++ b/app/policies/token_permission_type_policy.rb @@ -8,7 +8,7 @@ end def index? - user.can_use_api? && (user.organisation.token_permission_types.count > 0) + user.can_use_api? && (user.org.token_permission_types.count > 0) end diff --git a/app/policies/user_identifier_policy.rb b/app/policies/user_identifier_policy.rb new file mode 100644 index 0000000..e57f1c9 --- /dev/null +++ b/app/policies/user_identifier_policy.rb @@ -0,0 +1,20 @@ +class UserIdentifierPolicy < ApplicationPolicy + attr_reader :user_identifier + + def initialize(user, users) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @users = users + end + + def destroy? + !user.nil? + end + + class Scope < Scope + def resolve + scope.where(user_id: user.id) + end + end + +end \ No newline at end of file diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index bb44ae5..a97a91b 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -12,16 +12,16 @@ end def admin_grant_permissions? - @user.can_grant_permissions? && (@users.organisation_id == @user.organisation_id) + @user.can_grant_permissions? && (@users.org_id == @user.org_id) end def admin_update_permissions? - @user.can_grant_permissions? && (@users.organisation_id == @user.organisation_id) + @user.can_grant_permissions? && (@users.org_id == @user.org_id) end class Scope < Scope def resolve - scope.where(organisation_id: user.organisation_id) + scope.where(org_id: user.org_id) end end diff --git a/app/validators/answer_for_correct_template_validator.rb b/app/validators/answer_for_correct_template_validator.rb new file mode 100644 index 0000000..8ec15ee --- /dev/null +++ b/app/validators/answer_for_correct_template_validator.rb @@ -0,0 +1,10 @@ +class AnswerForCorrectTemplateValidator < ActiveModel::Validator + def validate(record) + # Make sure that the question and plan belong to the same template! + unless record.plan.nil? || record.question.nil? + unless record.plan.template == record.question.section.phase.template + record.errors[:question] << I18n.t('helpers.answer.question_must_belong_to_correct_template') + end + end + end +end \ No newline at end of file diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb new file mode 100644 index 0000000..a967c32 --- /dev/null +++ b/app/validators/url_validator.rb @@ -0,0 +1,7 @@ +class UrlValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + unless value =~ /https?:\/\/[-a-zA-Z0-9@:%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&\/=]*)?/ + record.errors[attribute] << (options[:message] || "is not a valid URL") + end + end +end \ No newline at end of file diff --git a/app/views/admin/dmptemplates/settings.html.erb b/app/views/admin/dmptemplates/settings.html.erb deleted file mode 100644 index 171d5bc..0000000 --- a/app/views/admin/dmptemplates/settings.html.erb +++ /dev/null @@ -1,38 +0,0 @@ -<% @settings.errors.full_messages.each do |error| %> -
    <%= error %>
    -<% end %> - -<%= form_for(@settings, url: update_settings_admin_dmptemplate_path(@template), method: :put, as: 'settings[export][formatting]', html: { class: 'formtastic' }) do |f| %> -
    - <%= t("admin.formatting")%> -
      -
    1. - <%= f.label(:font_face, t('helpers.settings.plans.font_face')) %> - <%= f.select(:font_face, options_for_select(Settings::Dmptemplate::VALID_FONT_FACES, @settings.formatting[:font_face]), as: 'formatting[font_face]') %> - <%= f.select(:font_size, options_for_select((1..36).to_a, @settings.formatting[:font_size])) %>pt -
    2. -
    3. - <%= f.label(t('helpers.settings.plans.margin')) %> - <% ["top", "bottom", "left", "right"].each do |pos| %> - <%= t("helpers.settings.plans.margins.#{pos}") -%> - <%= select_tag("settings[export][formatting][margin][#{pos}]", options_for_select((0..100).to_a, @settings.formatting[:margin][pos])) %> - <% end %> -
    4. -
    -
    - -
    - <%= t("admin.max_pages")%> -
      -
    1. - <%= label_tag('settings_export_max_pages', t('helpers.settings.plans.max_pages')) %> - <%= select_tag('settings[export][max_pages]', options_for_select((1..10).to_a, @settings.max_pages)) %> -
    2. -
    -
    - -
    - <%= submit_tag(t('helpers.save'), class: 'btn btn-primary') %> - <%= submit_tag(t('helpers.settings.plans.reset'), class: 'btn btn-primary') %> -
    -<% end %> diff --git a/app/views/administrate/application/_admin_header.html.erb b/app/views/administrate/application/_admin_header.html.erb new file mode 100644 index 0000000..115db95 --- /dev/null +++ b/app/views/administrate/application/_admin_header.html.erb @@ -0,0 +1,4 @@ +
    +

    Super Admin area

    + <%= link_to(image_tag("logo.jpg"), root_path)%> +
    diff --git a/app/views/administrate/application/_navigation.html.erb b/app/views/administrate/application/_navigation.html.erb new file mode 100644 index 0000000..a5cfa7a --- /dev/null +++ b/app/views/administrate/application/_navigation.html.erb @@ -0,0 +1,26 @@ +<%# Hack for customisation %> + +<%# +# Navigation + +This partial is used to display the navigation in Administrate. +By default, the navigation contains navigation links +for all resources in the admin dashboard, +as defined by the routes in the `admin/` namespace +%> + + diff --git a/app/views/administrate/application/_search.html.erb b/app/views/administrate/application/_search.html.erb new file mode 100644 index 0000000..7145011 --- /dev/null +++ b/app/views/administrate/application/_search.html.erb @@ -0,0 +1,21 @@ + diff --git a/app/views/annotations/_add_annotation.html.erb b/app/views/annotations/_add_annotation.html.erb new file mode 100644 index 0000000..8add942 --- /dev/null +++ b/app/views/annotations/_add_annotation.html.erb @@ -0,0 +1,32 @@ + +

    <%= _('Add Annotations') %>

    +<%= form_tag admin_create_annotation_path , class: 'add_annotation_form' do %> + + + + + + + + + +
    <%= _('Example Answer')%> +
      +
    • <%= text_area_tag :example_answer_text, nil, rows: 5 %> +
    • +
    +
    <%= _('Guidance')%> +
      +
    • <%= text_area_tag :guidance_text, nil, rows: 5 %> +
    • +
    +
    +
    + + +
    + <%= submit_tag _('Save'), class: "btn btn-primary" %> + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Cancel'), "#", class: "btn cancel cancel_add_annotations" %> +
    +<%end%> diff --git a/app/views/annotations/_edit_annotation.html.erb b/app/views/annotations/_edit_annotation.html.erb new file mode 100644 index 0000000..3a59362 --- /dev/null +++ b/app/views/annotations/_edit_annotation.html.erb @@ -0,0 +1,43 @@ + +<%= form_tag admin_update_annotation_path, method: :put do %> + <% example_answer_text = example_answer.present? ? example_answer.text : '' %> + <% guidance_text = guidance.present? ? guidance.text : '' %> + <%= hidden_field_tag :example_answer_id, example_answer.present? ? example_answer.id : nil %> + <%= hidden_field_tag :guidance_id, guidance.present? ? guidance.id : nil %> + + + + + + + + + + +
    <%= _('Example Answer')%> +
      +
    • <%= text_area_tag :example_answer_text, example_answer_text, rows: 5 %>
    • +
    +
    <%= _('Guidance')%> +
      +
    • <%= text_area_tag :guidance_text, guidance_text, rows: 5 %>
    • +
    +
    +
    + + +
    + <%= submit_tag _('Save'), class: 'btn btn-primary' %> + <% if example_answer.present? %> + <%= link_to _('Delete Example Answer'), admin_destroy_annotation_path(id: example_answer.id), + confirm: _("You are about to delete an example answer for '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-primary"%> + <% end %> + <% if guidance.present? %> + <%= link_to _('Delete Example Answer'), admin_destroy_annotation_path(id: guidance.id), + confirm: _("You are about to delete a guidance for '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-primary"%> + <% end %> + + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Cancel'), '#', class: 'btn cancel cancel_edit_annotations' %> +
    +<% end %> diff --git a/app/views/annotations/_show_annotation.html.erb b/app/views/annotations/_show_annotation.html.erb new file mode 100644 index 0000000..a790d70 --- /dev/null +++ b/app/views/annotations/_show_annotation.html.erb @@ -0,0 +1,26 @@ + +

    <%= _('Annotations') %>

    + + <% if example_answer.present? %> + + + + + <% end %> + <% if guidance.present? %> + + + + + <% end %> +
    + <%= _('Example Answer')%> + <%= raw example_answer.text %>
    + <%= _('Guidance')%> + <%= raw guidance.text %>
    +
    + +
    + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Edit Annotations'), '# ', class: "btn btn-primary edit_form_for_annotations"%> +
    diff --git a/app/views/answers/_form_fields.html.erb b/app/views/answers/_form_fields.html.erb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/views/answers/_form_fields.html.erb diff --git a/app/views/answers/_locking.html.erb b/app/views/answers/_locking.html.erb new file mode 100644 index 0000000..40a3d90 --- /dev/null +++ b/app/views/answers/_locking.html.erb @@ -0,0 +1,5 @@ +
    +

    <%= _('The following answer cannot be saved') %>

    + <%= render partial: '/answers/new_edit', locals: { question: question, answer: answer, readonly: true } %> +

    <%= _('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: user.name} %>

    +
    diff --git a/app/views/answers/_new_edit.html.erb b/app/views/answers/_new_edit.html.erb new file mode 100644 index 0000000..2434033 --- /dev/null +++ b/app/views/answers/_new_edit.html.erb @@ -0,0 +1,101 @@ + +<% q_format = question.question_format %> +<%= semantic_form_for answer, :url => {controller: :answers, action: :update }, html: {method: "put", class: "roadmap-form", 'data-autosave': question.id }, remote: true do |f| %> +
    + <% if !readonly %> + <%= f.input :id, as: :hidden, input_html: { value: answer.id } %> + <%= f.input :plan_id, as: :hidden, input_html: { value: answer.plan_id } %> + <%= f.input :user_id, as: :hidden, input_html: { value: answer.user_id } %> + <%= f.input :question_id, as: :hidden, input_html: { value: answer.question_id } %> + <%= f.input :lock_version, as: :hidden, input_html: { value: answer.lock_version } %> + <% end %> + + +

    + <%= raw question.text %> +

    + + + <% if !readonly && question.annotations.where(type: Annotation.types[:example_answer]).any? %> + <% annotation = question.annotations.where(type: Annotation.types[:example_answer]).order(:created_at).first %> + <% if annotation.text.present? %> +
    + + <%="#{annotation.org.abbreviation} "%> <%=_('Example of answer')%> + + +
    +

    + <%= raw annotation.text %> +

    +
    +
    + <% end %> + <% end %> + + <% if question.option_based? %> + <% options = question.question_options.by_number %> + <% if q_format.checkbox? %> +
      + <% options.each do |op| %> +
    1. + <%= f.check_box(:question_option_ids, { multiple: true, checked: answer.has_question_option(op.id), disabled: readonly }, op.id, nil) %> + <%= raw op.text %> +
    2. + <% end %> +
    + <% elsif q_format.radiobuttons? %> +
      + <% options.each do |op| %> +
    1. + <%= f.radio_button :question_option_ids, op.id, { checked: answer.has_question_option(op.id), id: "answer_option_ids_#{op.id}", disabled: readonly } %> + <%= raw op.text %> +
    2. + <% end %> +
    + <% elsif q_format.dropdown? || q_format.multiselectbox? %> + <% + options_html = "" + options.each do |op| + options_html += answer.has_question_option(op.id) ? + "" : + "" + end + %> + <%= select_tag('answer[question_option_ids]', raw(options_html), + {multiple: q_format.multiselectbox?, include_blank: q_format.dropdown?, disabled: readonly }) %> + <% end %> + + <% if question.option_comment_display == true %> + <%= label_tag('answer[text]', _('Comment')) %> + <% if readonly %> +

    <%= raw(answer.text) %>

    + <% else %> + <%= text_area_tag('answer[text]', answer.text, id: "answer-text-#{question.id}") %> + <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.tinymce_answer_events", content_css: asset_path('application.css')) %> + <% end %> + <%end%> + <% end %> + + <% if q_format.textfield? %> + <% if readonly %> +

    <%= strip_tags(answer.text) %>

    + <% else %> + <%= text_field_tag('answer[text]', strip_tags(answer.text)) %> + <% end %> + <% elsif q_format.textarea? %> + <% if readonly %> +

    <%= raw(answer.text) %>

    + <% else %> + <%= text_area_tag('answer[text]', answer.text, id: "answer-text-#{question.id}") %> + <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.tinymce_answer_events", content_css: asset_path('application.css')) %> + <% end %> + <% end %> + + <% if !readonly %> + + <% end %> +
    + <% end %> \ No newline at end of file diff --git a/app/views/answers/_status.html.erb b/app/views/answers/_status.html.erb new file mode 100644 index 0000000..ddf8dcf --- /dev/null +++ b/app/views/answers/_status.html.erb @@ -0,0 +1,9 @@ + + + +
    + <% if answer.updated_at.blank? %> + <%= _('Not answered yet') %> + <% else %> + <%= _('Answered')%> <%= answer.updated_at.iso8601 %><%= _(' by')%> <%= answer.user.name %> + <% end %> \ No newline at end of file diff --git a/app/views/answers/update.js.erb b/app/views/answers/update.js.erb new file mode 100644 index 0000000..2290a67 --- /dev/null +++ b/app/views/answers/update.js.erb @@ -0,0 +1,26 @@ +// partial /answers/locking +<% if @stale_answer %> + $("#answer-locking-<%= @question.id%>") + .html("<%= escape_javascript(render partial: '/answers/locking', locals: { question: @question, answer: @stale_answer, user: @answer.user }) %>"); +<% else %> + $("#answer-locking-<%= @question.id%>").html(""); +<% end %> + +// partial /answer/new_edit +if(tinymce) + tinymce.remove("#answer-text-<%= @question.id %>"); +$("#answer-form-<%= @question.id%>") + .html("<%= escape_javascript(render partial: '/answers/new_edit', locals: { question: @question, answer: @answer, readonly: false }) %>"); + +// partial /answer/status +$("#answer-status-<%= @question.id %>") + .html("<%= escape_javascript(render partial: '/answers/status', locals: { answer: @answer}) %>"); +if($.fn.init_answer_status) + $.fn.init_answer_status(); + +// partial /plans/progress +$(".progress").html("<%= escape_javascript(render :partial => '/plans/progress', locals: { plan: @plan }) %>"); + +// partial /sections/progress +$("#section-progress-<%= @section.id %>") + .html("<%= escape_javascript(render partial: '/sections/progress', locals: { section: @section, plan: @plan }) %>"); \ No newline at end of file diff --git a/app/views/api/v0/dmptemplates/index.json.jbuilder b/app/views/api/v0/dmptemplates/index.json.jbuilder deleted file mode 100644 index 33ebd74..0000000 --- a/app/views/api/v0/dmptemplates/index.json.jbuilder +++ /dev/null @@ -1,14 +0,0 @@ -# builds a json response to api query for a list of all dmptemplates -json.prettify! - -json.templates Organisation.all.each do |org| - unless org.published_templates.blank? - json.organisation_name org.name - json.organisation_id org.id - json.organisation_templates org.published_templates.each do |template| - json.title template.title - json.id template.id - json.description template.description - end - end -end \ No newline at end of file diff --git a/app/views/api/v0/guidance_groups/index.json.jbuilder b/app/views/api/v0/guidance_groups/index.json.jbuilder index 908b19d..7a5fd3d 100644 --- a/app/views/api/v0/guidance_groups/index.json.jbuilder +++ b/app/views/api/v0/guidance_groups/index.json.jbuilder @@ -5,17 +5,13 @@ json.name guidance_group.name json.id guidance_group.id - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - json.id template.id - end - json.optional guidance_group.optional_subset json.updated guidance_group.updated_at -end + json.guidances guidance_group.guidances.each do |guidance| + json.text guidance.text + json.updated guidance.updated_at + json.themes guidance.themes.each do |theme| + json.title theme.title + end + end +end \ No newline at end of file diff --git a/app/views/api/v0/guidance_groups/show.json.jbuilder b/app/views/api/v0/guidance_groups/show.json.jbuilder deleted file mode 100644 index 1a412db..0000000 --- a/app/views/api/v0/guidance_groups/show.json.jbuilder +++ /dev/null @@ -1,25 +0,0 @@ -# builds a json response to api query for a list of guidance groups -json.prettify! - -json.guidance_group do - json.name @guidance_group.name - json.id @guidance_group.id - - # for each template associated with the guidance group, list the template name - @templates = @guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - json.id template.id - end - - json.guidances @guidance_group.guidances do |guidance| - json.text guidance.text - json.id guidance.id - end - json.optional @guidance_group.optional_subset - json.updated @guidance_group.updated_at -end diff --git a/app/views/api/v0/guidances/index.json.jbuilder b/app/views/api/v0/guidances/index.json.jbuilder deleted file mode 100644 index 82edd20..0000000 --- a/app/views/api/v0/guidances/index.json.jbuilder +++ /dev/null @@ -1,29 +0,0 @@ -# builds a json response to api querry for all guidances - -json.prettify! - -json.guidance @all_viewable_guidances do |guidance| - json.id guidance.id - json.text guidance.text - json.updated_at guidance.updated_at - - # each guidance may be associated with many guidance groups - @guidance_groups = guidance.guidance_groups - json.guidance_groups @guidance_groups do |guidance_group| - json.name guidance_group.name - json.id guidance_group.id - - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - end - json.optional guidance_group.optional_subset - json.updated guidance_group.updated_at - end - -end diff --git a/app/views/api/v0/guidances/show.json.jbuilder b/app/views/api/v0/guidances/show.json.jbuilder deleted file mode 100644 index be04df7..0000000 --- a/app/views/api/v0/guidances/show.json.jbuilder +++ /dev/null @@ -1,30 +0,0 @@ -# builds a json response to api querry for a specific guidance - -json.prettify! - -json.guidance do - json.id @guidance.id - json.text @guidance.text - json.updated_at @guidance.updated_at - - # each guidance may be associated with many guidance groups - @guidance_groups = @guidance.guidance_groups - unless @guidance_groups.empty? - json.guidance_groups @guidance_groups do |guidance_group| - json.name guidance_group.name - json.id guidance_group.id - - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - end - json.optional guidance_group.optional_subset - json.updated guidance_group.updated_at - end - end -end \ No newline at end of file diff --git a/app/views/api/v0/plans/create.json.jbuilder b/app/views/api/v0/plans/create.json.jbuilder new file mode 100644 index 0000000..0c3b359 --- /dev/null +++ b/app/views/api/v0/plans/create.json.jbuilder @@ -0,0 +1,12 @@ +# builds a json response to a successful project createtion + +json.prettify! + +json.plan do + json.title @plan.title + json.template @plan.template.title + # TODO add after decision on user creation/identification + json.created_by @plan.owner.email + json.id @plan.id + json.created_at @plan.created_at +end \ No newline at end of file diff --git a/app/views/api/v0/plans/show.json.jbuilder b/app/views/api/v0/plans/show.json.jbuilder new file mode 100644 index 0000000..2cd84bf --- /dev/null +++ b/app/views/api/v0/plans/show.json.jbuilder @@ -0,0 +1,13 @@ +# builds a json response to a successful project createtion + +json.prettify! + +json.project do + json.title @project.title + # TODO add after decision on user creation/identification + json.created_by @project.owner.email + json.id @project.id + json.created_at @project.created_at + #json.template @project.dmptemplate + json.dmptemplate @project.dmptemplate.title +end diff --git a/app/views/api/v0/projects/create.json.jbuilder b/app/views/api/v0/projects/create.json.jbuilder deleted file mode 100644 index ebb8c58..0000000 --- a/app/views/api/v0/projects/create.json.jbuilder +++ /dev/null @@ -1,15 +0,0 @@ -# builds a json response to a successful project createtion - -json.prettify! - -json.project do - json.title @project.title - # TODO add after decision on user creation/identification - #json.created_by @project.owner.email - json.id @project.id - json.created_at @project.created_at -end - -# json.location do -# json.link (url_for action: 'show', controller: 'project') -# end diff --git a/app/views/api/v0/projects/show.json.jbuilder b/app/views/api/v0/projects/show.json.jbuilder deleted file mode 100644 index 2cd84bf..0000000 --- a/app/views/api/v0/projects/show.json.jbuilder +++ /dev/null @@ -1,13 +0,0 @@ -# builds a json response to a successful project createtion - -json.prettify! - -json.project do - json.title @project.title - # TODO add after decision on user creation/identification - json.created_by @project.owner.email - json.id @project.id - json.created_at @project.created_at - #json.template @project.dmptemplate - json.dmptemplate @project.dmptemplate.title -end diff --git a/app/views/api/v0/statistics/plans.json.jbuilder b/app/views/api/v0/statistics/plans.json.jbuilder index 1a05c9b..fdefac1 100644 --- a/app/views/api/v0/statistics/plans.json.jbuilder +++ b/app/views/api/v0/statistics/plans.json.jbuilder @@ -1,25 +1,22 @@ json.prettify! -json.plans @org_projects.each do |project| - json.id project.id - json.grant_number project.grant_number - json.org_id project.organisation_id +json.plans @org_plans.each do |plan| + json.id plan.id + json.grant_number plan.grant_number + json.title plan.title json.template do - json.title project.dmptemplate.title - json.id project.dmptemplate.id - end - json.project do - json.title project.title + json.title plan.template.title + json.id plan.template.dmptemplate_id end json.funder do - json.name project.funder_name + json.name (plan.template.org.funder? ? plan.template.org.name : '') end json.principal_investigator do - json.name project.principal_investigator + json.name plan.principal_investigator end json.data_contact do - json.info project.data_contact + json.info plan.data_contact end - json.description project.description + json.description plan.description end \ No newline at end of file diff --git a/app/views/api/v0/statistics/plans_by_template.json.jbuilder b/app/views/api/v0/statistics/plans_by_template.json.jbuilder index 155bbba..9a7efd8 100644 --- a/app/views/api/v0/statistics/plans_by_template.json.jbuilder +++ b/app/views/api/v0/statistics/plans_by_template.json.jbuilder @@ -1,20 +1,7 @@ json.prettify! -templates = {} -@org_projects.each do |project| - # if hash exists - if templates[project.dmptemplate.title].blank? - templates[project.dmptemplate.title] = {} - templates[project.dmptemplate.title][:title] = project.dmptemplate.title - templates[project.dmptemplate.title][:id] = project.dmptemplate.id - templates[project.dmptemplate.title][:uses] = 1 - else - templates[project.dmptemplate.title][:uses] += 1 - end -end -json.templates templates.each do |template, info| +json.templates @templates.each do |template, info| json.template_name info[:title] json.template_id info[:id] json.template_uses info[:uses] -end - +end \ No newline at end of file diff --git a/app/views/api/v0/statistics/using_template.json.jbuilder b/app/views/api/v0/statistics/using_template.json.jbuilder index 04a77b6..9a7efd8 100644 --- a/app/views/api/v0/statistics/using_template.json.jbuilder +++ b/app/views/api/v0/statistics/using_template.json.jbuilder @@ -1,3 +1,7 @@ json.prettify! -json.plans_using_template @template_count \ No newline at end of file +json.templates @templates.each do |template, info| + json.template_name info[:title] + json.template_id info[:id] + json.template_uses info[:uses] +end \ No newline at end of file diff --git a/app/views/api/v0/templates/index.json.jbuilder b/app/views/api/v0/templates/index.json.jbuilder new file mode 100644 index 0000000..5f9b5ff --- /dev/null +++ b/app/views/api/v0/templates/index.json.jbuilder @@ -0,0 +1,19 @@ +# builds a json response to api query for a list of all dmptemplates +json.prettify! + +json.templates @org_templates.each do |org, templates| + json.organisation_name org.name + json.organisation_id org.id + json.is_funder org.funder? + json.organisation_templates templates[:own].each do |_, template| + json.title template.title + json.id template.dmptemplate_id + json.description template.description + end + json.customized_templates templates[:cust].each do |_,template| + json.title template.title + json.id template.dmptemplate_id + json.customization_of template.customization_of + json.description template.description + end +end \ No newline at end of file diff --git a/app/views/contact_us/contacts/new.html.erb b/app/views/contact_us/contacts/new.html.erb index 73562ec..c4d2f30 100644 --- a/app/views/contact_us/contacts/new.html.erb +++ b/app/views/contact_us/contacts/new.html.erb @@ -1,114 +1,111 @@ - +<% javascript "contacts/new_contact.js" %> +

    - <%= t("contact_page.title") %> + <%= _("Contact Us") %>

    - <%= raw t("contact_page.intro_text_html", - organisation_name: Rails.configuration.branding[:organisation][:name], - organisation_email: Rails.configuration.branding[:organisation][:email], - organisation_url: Rails.configuration.branding[:organisation][:url], - application_name: Rails.configuration.branding[:application][:name], - application_url: Rails.configuration.branding[:application][:url], - application_issue_list_url: Rails.configuration.branding[:application][:issue_list_url]) %> - <%= raw t("contact_page.github_text_html") %> + <%= raw _('%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below.') % {organisation_name: Rails.configuration.branding[:organisation][:name], + organisation_url: Rails.configuration.branding[:organisation][:url], + application_name: Rails.configuration.branding[:application][:name]} %>

    - -
    -
    - <%= form_for @contact, :url => contacts_path do |f| %> -
    - - <% if ContactUs.require_name %> - - - - - <% end %> - - - - - <% if ContactUs.require_subject %> - - - - - <% end %> - - - - - <% if !user_signed_in? then %> - - - - - <% end %> -
    - <%= f.label :name, (t('.name') + content_tag(:abbr, "*", :class => "required")).html_safe %> - - <% if user_signed_in? then %> - <%= f.text_field :name, :value => current_user.name(false) %> - <% else %> - <%= f.text_field :name %> - <% end %> - <% if f.object.errors[:name].present? %> -

    <%= f.object.errors[:name].join(" and ") %>

    - <% end %> -
    - <%= f.label :email, (t('.email') + content_tag(:abbr, "*", :class => "required")).html_safe %> - - <% if user_signed_in? then %> - <%= f.email_field :email, :value => current_user.email %> - <% else %> - <%= f.email_field :email %> - <% end %> - <% if f.object.errors[:email].present? %> -

    <%= f.object.errors[:email].join(" and ") %>

    - <% end %> -
    - <%= f.label :subject, (t('.subject') + content_tag(:abbr, "*", :class => "required")).html_safe %> - - <%= f.text_field :subject %> - <% if f.object.errors[:subject].present? %> -

    <%= f.object.errors[:subject].join(" and ") %>

    - <% end %> -
    - <%= f.label :message, (t('.message') + content_tag(:abbr, "*", :class => "required")).html_safe %> - - <%= f.text_area :message, :rows => 10 %> - <% if f.object.errors[:message].present? %> -

    <%= f.object.errors[:message].join(" and ") %>

    - <% end %> -
    - <%= t('helpers.security_check') %> - - <%= recaptcha_tags %> -
    -
    -
    - <%= f.submit :submit, :class => "btn btn-primary", :label => t('.submit') %> -
    - <% end %> -
    -
    - -
    -
    - <%= raw t("contact_page.address_text_html", - organisation_name: Rails.configuration.branding[:organisation][:name], - organisation_email: Rails.configuration.branding[:organisation][:email], - application_name: Rails.configuration.branding[:application][:name],) %> - -
    - + +
    +
    + <%= form_for @contact, url: contacts_path, html: {class: "roadmap-form"} do |f| %> +
    + <% if ContactUs.require_name %> +
    + <%= f.label :name, (_('Name') + content_tag(:abbr, "*", class: "required")).html_safe %> + <% if user_signed_in? then %> + <%= f.text_field :name, value: current_user.name(false) %> + <% else %> + <%= f.text_field :name %> + <% end %> + <% if f.object.errors[:name].present? %> +

    <%= f.object.errors[:name].join(_(" and ")) %>

    + <% end %> +
    + <% end %> + +
    + <%= f.label :email, (_('Email') + content_tag(:abbr, "*", class: "required")).html_safe %> + <% if user_signed_in? then %> + <%= f.email_field :email, value: current_user.email %> + <% else %> + <%= f.email_field :email %> + <% end %> + <% if f.object.errors[:email].present? %> +

    <%= f.object.errors[:email].join(_(" and ")) %>

    + <% end %> +
    + + <% if ContactUs.require_subject %> +
    + <%= f.label :subject, (_('Subject') + content_tag(:abbr, "*", class: "required")).html_safe %> + <%= f.text_field :subject %> + <% if f.object.errors[:subject].present? %> +

    <%= f.object.errors[:subject].join(_(" and ")) %>

    + <% end %> +
    + <% end %> + +
    + <%= f.label :message, (_('Message') + content_tag(:abbr, "*", class: "required")).html_safe %> + <%= f.text_area :message, rows: 10, class: "input-large" %> + <% if f.object.errors[:message].present? %> +

    <%= f.object.errors[:message].join(_(" and ")) %>

    + <% end %> +
    + + <% if !user_signed_in? then %> +
    + <%= t('helpers.security_check') %> + <%= recaptcha_tags %> +
    + <% end %> + +
    + + <%= render partial: 'shared/accessible_submit_button', + locals: {id: 'create_contact_submit', + val: 'Submit', + disabled_initially: true, + tooltip: _('Fill in the required fields')} %> +
    +
    -
    -
    -
    + <% end %> +
    +
    + + +
    +
    + <%= raw _("
    • %{organisation_name}
    • +
    • %{organisation_address_line1}
    • +
    • %{organisation_address_line2}
    • +
    • %{organisation_address_line3}
    • +
    • %{organisation_address_line4}
    • +
    • %{organisation_address_country}
    • +
    +

    Helpline: %{organisation_telephone}

    +

    Email %{organisation_email}

    ") % + { organisation_name: Rails.configuration.branding[:organisation][:name], + organisation_address_line1: Rails.configuration.branding[:organisation][:address_line1], + organisation_address_line2: Rails.configuration.branding[:organisation][:address_line2], + organisation_address_line3: Rails.configuration.branding[:organisation][:address_line3], + organisation_address_line4: Rails.configuration.branding[:organisation][:address_line4], + organisation_address_country: Rails.configuration.branding[:organisation][:address_country], + organisation_telephone: Rails.configuration.branding[:organisation][:telephone], + organisation_email: Rails.configuration.branding[:organisation][:email], + application_name: Rails.configuration.branding[:application][:name]} %> + +
    + + +
    +
    +
    +
    diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb index c1faca5..0576cc7 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.erb +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -1,5 +1,7 @@ -

    <%= t('custom_devise.welcome_to_DMP') %>, <%= @email %>!

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _("Welcome to %{application_name}") % {application_name: Rails.configuration.branding[:application][:name]} %>, <%= @email %>!

    -

    <%= t('custom_devise.thank_you_and_confirm') %>

    +

    <%= _("Thank you for registering. Please confirm your email address") %>:

    -

    <%= link_to t('custom_devise.click_to_confirm'), confirmation_url(@resource, :confirmation_token => @token) %> <%= t('custom_devise.1st_part_copy') %> <%= confirmation_url(@resource, :confirmation_token => @token) %> <%= t('custom_devise.2nd_part_copy') %>

    \ No newline at end of file +

    <%= link_to _("Click here to confirm your account"), confirmation_url(@resource, :confirmation_token => @token) %> (<%= _("or copy") %> <%= confirmation_url(@resource, :confirmation_token => @token) %> <%= _("into your browser") %>).

    +<% end %> \ No newline at end of file diff --git a/app/views/devise/mailer/invitation_instructions.html.erb b/app/views/devise/mailer/invitation_instructions.html.erb index 7beb75d..c7235c1 100644 --- a/app/views/devise/mailer/invitation_instructions.html.erb +++ b/app/views/devise/mailer/invitation_instructions.html.erb @@ -1,7 +1,8 @@ -

    <%= t('custom_devise.hello') %> <%= @resource.email %>!

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _("Hello") %> <%= @resource.email %>,

    +

    <%= _("A colleague has invited you to contribute to their Data Management Plan at ") %> <%= link_to Rails.configuration.branding[:application][:name], root_url %>.

    +

    <%= link_to _("Click here to accept the invitation"), accept_invitation_url(@resource, :invitation_token => @token) %> (<%= _("or copy") %> <%= accept_invitation_url(@resource, :invitation_token => @token) %> <%= _("into your browser") %>).

    +

    <%= _("If you don't want to accept the invitation, please ignore this email.") %>
    <%= _("Your account won't be created until you access the link above and set your password.") %>

    +

    <%=_('All the best,')%>
    <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>.

    -

    <%= t('custom_devise.colleague_invited_you') %> <%= link_to t('tool_title'), root_url %>

    - -

    <%= link_to t('custom_devise.click_to_accept'), accept_invitation_url(@resource, :invitation_token => @token) %> <%= t('custom_devise.1st_part_copy') %> <%= accept_invitation_url(@resource, :invitation_token => @token) %> <%= t('custom_devise.2nd_part_copy') %>

    - -<%= t('custom_devise.ignore_wont_be_created') %> \ No newline at end of file +<% end %> diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb index b4c0ac6..55858c9 100644 --- a/app/views/devise/mailer/reset_password_instructions.html.erb +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -1,7 +1,13 @@ -

    <%= t('custom_devise.hello') %> <%= @resource.email %>!

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _("Hello ") %><%= @resource.email %>

    -

    <%= t('custom_devise.1st_part_change_password') %> <%= link_to t('tool_title'), root_url %> <%= t('custom_devise.2nd_part_change_password') %>

    +

    <%= _("Someone has requested a link to change your ") %><%= Rails.configuration.branding[:application][:name] %><%= _(" password. You can do this through the link below.") %>

    -

    <%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %>

    +

    <%= link_to _('Change my password'), edit_password_url(@resource, :reset_password_token => @token) %>

    -<%= t('custom_devise.1st_part_change_password') %> +

    <%= _("If you didn't request this, please ignore this email.") %>

    + +

    + <%= _("Many thanks,") %>
    <%= _('The ') %><%= Rails.configuration.branding[:application][:name] %><%= _(' team') %> +

    +<% end %> \ No newline at end of file diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb index 0346189..3787b7a 100644 --- a/app/views/devise/mailer/unlock_instructions.html.erb +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -1,7 +1,9 @@ -

    <%= t('custom_devise.hello') %> <%= @resource.email %>!

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _("Hello") %> <%= @resource.email %>!

    -

    <%= t('custom_devise.1st_part_locked') %><%= link_to t('tool_title'), root_url %><%= t('custom_devise.2nd_part_locked') %>

    +

    <%= _("Your") %> <%= link_to Rails.configuration.branding[:application][:name], root_url %> <%= _("account has been locked due to an excessive number of unsuccessful sign in attempts.") %>

    -

    <%= t('custom_devise.click_to_unlock') %>

    +

    <%= _("Click the link below to unlock your account") %>:

    -

    <%= link_to t('custom_devise.unlock'), unlock_url(@resource, :unlock_token => @token) %>

    \ No newline at end of file +

    <%= link_to _("Unlock my account"), unlock_url(@resource, :unlock_token => @token) %>

    +<% end %> \ No newline at end of file diff --git a/app/views/devise/registrations/_external_identifier.html.erb b/app/views/devise/registrations/_external_identifier.html.erb new file mode 100644 index 0000000..226b270 --- /dev/null +++ b/app/views/devise/registrations/_external_identifier.html.erb @@ -0,0 +1,21 @@ +
    + <% if id.nil? || id.identifier == '' %> + <%= link_to "#{_("Link account with #{scheme.description} ID")}", + Rails.application.routes.url_helpers.send( + "user_#{scheme.name.downcase}_omniauth_authorize_path" + ), + title: t("identifier_schemes.schemes.#{scheme.name}.connect_tooltip", default: "") + %> + <% else %> + <% if scheme.user_landing_url.nil? %> + <%= _("Your account has been linked to #{scheme.description}.") %> + <% else %> + <%= link_to "#{_("Your account has been linked to #{scheme.description}.")}", "#{scheme.user_landing_url}/#{id.identifier}", target: '_blank', + title: t("identifier_schemes.schemes.#{scheme.name}.connect_tooltip", default: "") %> + <% end %> + <%= link_to ''.html_safe, + destroy_user_identifier_path(id), method: :delete, + title: _("Unlink your account from #{scheme.description}. You can link again at any time."), + data: {confirm: _("Are you sure you want to unlink #{scheme.description} ID?")} %> + <% end %> +
    diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 5ff15d9..8bb0f82 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,150 +1,117 @@ -

    <%= t("helpers.edit_profile") %>

    - -<%= raw t("helpers.user_details_text_html") %> +
    +

    <%= _('Edit profile') %>

    -
    - <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:method => :put}) do |f| %> - <%= hidden_field_tag :unlink_flag, "false", :id => "unlink_flag" %> - -
    +

    + <%= _("Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in.") %> +

    -

    <%= raw t("helpers.user_details_paragraph_html") %>

    + <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put, class: "roadmap-form white_background"}) do |f| %> + +
    + <%= _('You can edit any of the details below.') %> + + <%= hidden_field_tag :unlink_flag, "false", id: "unlink_flag" %> - - - - - - - - - - - - - - - - - - <% other_organisations = Array.new %> - <% Organisation.where("parent_id IS ? AND is_other = ?", nil, true).each do |org| %> - <% other_organisations << org.id %> - <% end %> - "> - - - - - - - - - - - - <% unless @user.api_token.blank? %> - - - - - - - - - <% end %> -
    <%= (t("helpers.email") + " *") %><%= f.email_field :email, :as => :email %>
    <%= t("helpers.first_name") %><%= f.text_field :firstname, :as => :string, - :id => "first_time_login_firstname", - :autofocus => true, - :class => "text_field has-tooltip", - "data-toggle" => "tooltip", - "data-trigger" => "focus" , - "title" => t("helpers.first_name_help_text") %>
    <%= t("helpers.last_name") %><%= f.text_field :surname, - :as => :string, :id => "first_time_login_surname", - :class => "text_field has-tooltip", - "data-toggle" => "tooltip", - "data-trigger" => "focus" , - "title" => t("helpers.surname_help_text") %>
    <%= t("helpers.org_type.organisation") %><%= collection_select(:user, - :organisation_id, Organisation.where("parent_id IS NULL").order("name"), - :id, :name, {include_blank: constant("organisation_types.organisation")}, - { :class => "typeahead org_sign_up" }) %>
    <%= t('helpers.user_details_language') %> - - - -
    <%= t("helpers.orcid_id") %><%= f.text_field :orcid_id , - :as => :string, - :autocomplete => "off" , - :class => "text_field has-tooltip", "data-toggle" => "tooltip", "data-html" => "true", "title" => t("helpers.orcid_html") %>
    <%= t("helpers.api_token") %><%= @user.api_token %>
    <%= t("helpers.api_info") %><%= link_to( t("helpers.api_use"), controller: "token_permission_types", action: "index")%>
    -
    -

    - <% if Rails.application.config.shibboleth_enabled %> - <% if resource.shibboleth_id.nil? || resource.shibboleth_id.length == 0 then %> - <%= link_to t("helpers.shibboleth_to_link_text"), user_omniauth_shibboleth_path, :class => "a-orange" %> +

    + <%= f.label :email, _('Email') + " *" %> + <%= f.email_field :email, as: :email, class: "input-medium has-tooltip", + "data-toggle": "tooltip", "data-trigger": "focus", + "title": _('Please enter your current password below when changing your email address.') %> +
    +
    + <%= f.label :firstname, _('First name')+ " *" %> + <%= f.text_field :firstname, as: :string, + id: "first_time_login_firstname", + autofocus: true, + class: "input-medium has-tooltip", + "data-toggle" => "tooltip", + "data-trigger" => "focus" , + "title" => _('Please enter your first name.') %> +
    +
    + <%= f.label :surname, _('Last name') + " *" %> + <%= f.text_field :surname, as: :string, id: "first_time_login_surname", + class: "input-medium has-tooltip", "data-toggle" => "tooltip", + "data-trigger" => "focus" , + "title" => _('Please enter your surname or family name.') %> +
    +
    + <%= f.label :org, _('Organisation') + " *" %> + <%= render partial: "shared/accessible_combobox", + locals: {name: "#{resource_name}[org_name]", + id: "#{resource_name}_org_name", + default_selection: @default_org, + models: @orgs, + attribute: 'name', + classes: 'fixed-width-large'} %> +
    + + <% if MANY_LANGUAGES %> +
    + <% lang = current_user.language.nil? ? FastGettext.default_locale : current_user.language.abbreviation %> + <%= f.label :language, _('Language') %> + +
    + <% end %> + + <% @identifier_schemes.each do |scheme| %> +
    + +
    + <%= render partial: 'external_identifier', + locals: {scheme: scheme, + id: current_user.identifier_for(scheme)} %> +
    +
    + <% end %> -
    -
    + <% unless @user.api_token.blank? %> +
    + <%= f.label :api_token, _('API token') %><%= @user.api_token %> +
    +
    + <%= link_to( _('How to use the API'), controller: "token_permission_types", action: "index")%> +
    + <% end %> +
    + + <%= _('If you would like to change your password please complete the following fields.') %> - - diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index 5406165..0c689be 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -1,7 +1,7 @@ -

    <%= t('helpers.sign_up') %>

    -<% unless session[:shibboleth_data].nil? %> +

    <%= _('Create account') %>

    +<% unless session["devise.shibboleth_data"].nil? %>

    - <%= raw t('helpers.sign_up_shibboleth_alert_text_html')%> + <%= (_("%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly.") % { :application_name => Rails.configuration.branding[:application][:name] }).html_safe %>

    <% cookies[:show_shib_link] = { value: 'show_shib_link', expires: 3.hours.from_now } %> <% end %> @@ -10,4 +10,4 @@
    <%= render :partial => 'shared/register_form', locals: {extended: true} %> -
    \ No newline at end of file + diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 95c5cf1..90556a7 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,15 +1,15 @@ -

    <%= t("helpers.sign_in") %>

    +

    <%= _('Sign in') %>

    <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
    - + - + @@ -24,7 +24,7 @@
    <%= t("helpers.email") %><%= _('Email') %> <%= f.email_field :email, :autofocus => true %>
    <%= t("helpers.password") %><%= _('Password') %> <%= f.password_field :password %>
    - <%= f.submit t("helpers.sign_in"), :class => "btn btn-primary" %> + <%= f.submit _('Sign in'), :class => "btn btn-primary" %>
    <% end %> diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb index 44a1965..3469473 100644 --- a/app/views/devise/shared/_links.erb +++ b/app/views/devise/shared/_links.erb @@ -1,13 +1,13 @@ <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> - <%= link_to t('helpers.forgot_password'), new_password_path(resource_name), :class => "a-orange"%>
    + <%= link_to _('Forgot your password?'), new_password_path(resource_name), :class => "a-orange"%>
    <% end -%> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to t('helpers.no_pass_instructions'), new_confirmation_path(resource_name), :class => "a-orange"%>
    + <%= link_to _("Didn't receive confirmation instructions?"), new_confirmation_path(resource_name), :class => "a-orange"%>
    <% end -%> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to t('helpers.no_unlock_instructions'), new_unlock_path(resource_name), :class => "a-orange" %>
    + <%= link_to _("Didn't receive unlock instructions?"), new_unlock_path(resource_name), :class => "a-orange" %>
    <% end -%> <%#- if devise_mapping.omniauthable? %> diff --git a/app/views/dmptemplates/_add_guidance.html.erb b/app/views/dmptemplates/_add_guidance.html.erb deleted file mode 100644 index de49775..0000000 --- a/app/views/dmptemplates/_add_guidance.html.erb +++ /dev/null @@ -1,93 +0,0 @@ - -
    - <%= form_for :guidance, :url => {:action => "admin_create"}, :html => {:id => "new_guidance_form"} do |f| %> - - - - - - - - - - - - - - - - - -
    <%= t("org_admin.guidance.text_label") %>
    - <%= text_area_tag("guidance-text", "", class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "guidance_text_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.guidance.text_help_text_html"))%> -
    -
    -
    <%= t("org_admin.guidance.by_theme_or_by_question") %>
    - <%= select_tag "g_options", options_for_select([[t("org_admin.guidance.by_themes_label"), 1], - [t("org_admin.guidance.by_question_label"), 2]]) %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "guidance_apply_to_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.guidance.apply_to_help_text_html"))%> -
    -
    - - -
    <%= t("org_admin.guidance.published") %>
    - <%= f.check_box :published , :as => :check_boxes%> -
    -
    - -
    -
    <%= t("org_admin.guidance.guidance_group_label") %>
    - <%= f.collection_select(:guidance_group_ids, - GuidanceGroup.where("organisation_id = ?", current_user.organisation_id).order("name ASC"), - :id, :name, {:prompt => false, :include_blank => t('helpers.none')}, {:multiple => false})%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "guidance_group_select_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.guidance.guidance_group_select_help_text_html"))%> -
    -
    - -
    - - - -
    - <%= t("helpers.submit.save")%> - - <%= link_to t("helpers.submit.cancel"), :back, :class => "btn cancel" %> -
    - -
    - <%= tinymce :content_css => asset_path("application.css") %> - <%end%> -
    - - - - - \ No newline at end of file diff --git a/app/views/dmptemplates/_add_question.html.erb b/app/views/dmptemplates/_add_question.html.erb deleted file mode 100644 index 1caf54c..0000000 --- a/app/views/dmptemplates/_add_question.html.erb +++ /dev/null @@ -1,179 +0,0 @@ - - -<% @new_question = Question.new %> -<% @new_question.number = section.questions.count + 1 %> - - -<%= form_for @new_question, :url => {:action => "admin_createquestion"}, :html => {:id => "new_question_#{section.id}"} do |f| %> -<%= f.hidden_field :section_id, :value => section.id %> -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= t("org_admin.questions.question_number_label")%><%= f.number_field :number, :in => 1..50, :class => "number_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.questions.number_help_text") %> - -
    -
    <%= t("org_admin.questions.question_text_label")%><%= f.text_area :text, :rows => "5", :id => "new_question_text_#{section.id}" %> -
    -
    <%= t("org_admin.questions.answer_format_label")%><%= f.hidden_field :section_id, :value => section.id, :class => "section_id" %> -
    -
    - <%= f.select :question_format_id, - options_from_collection_for_select(QuestionFormat.all.order("title"), :id, :title, QuestionFormat.find_by_title(t("helpers.text_area")).id), - {}, :id => "new-select-format-#{section.id}"%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_format_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_format_help_text_html"))%> -
    - -
    -
    - - -
    - - -
    - - -
    - -
    -
    -
    -
    <%= t("org_admin.questions.suggested_or_example_answer_label")%>
    - <% suggested_answer = @new_question.suggested_answers.build %> - <%= f.fields_for :suggested_answers, suggested_answer do |s|%> - <%= s.hidden_field :organisation_id, :value => current_user.organisation.id %> -
      -
    • <%= s.select :is_example, {t("org_admin.questions.example_answer_label") => true, t("org_admin.questions.suggested_answer_label") => false} %>
    • -
    • <%= s.text_area :text, :rows => 5 %>
    • -
    - <%end%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "suggested_answer_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.suggested_answer_help_text_html"))%> -
    -
    -
    - -
    <%= t("org_admin.questions.guidance_label")%>
    - <%= text_area_tag("new-question-guidance", "", class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_guidance_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_guidance_help_text_html"))%> -
    -
    -
    -
    <%= t("org_admin.questions.themes_label")%>
    - <%= f.collection_select(:theme_ids, - Theme.all.order("title"), - :id, :title, {:prompt => false, :include_blank => t('helpers.none')}, {:multiple => true})%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_themes_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_themes_help_text_html"))%> -
    - - -
    -
    - - -
    - <%= hidden_field_tag :section_id, section.id, :class => "section_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary new_question_save_button" %> - <%= hidden_field_tag :section_id, section.id, :class => "section_id_new" %> - <%= link_to t("helpers.submit.cancel"), '#', :class => "btn cancel cancel_add_new_question" %> -
    -
    - -<%end%> - diff --git a/app/views/dmptemplates/_add_section.html.erb b/app/views/dmptemplates/_add_section.html.erb deleted file mode 100644 index b445c85..0000000 --- a/app/views/dmptemplates/_add_section.html.erb +++ /dev/null @@ -1,54 +0,0 @@ - - -<% @new_section = Section.new %> -<% @new_section.number = version.sections.count + 1 %> - - -<%= form_for @new_section, :url => {:action => "admin_createsection"} do |f| %> - <%= f.hidden_field :version_id, :value => version.id %> - <%= f.hidden_field :organisation_id, :value => current_user.organisation.id %> - -
    -
    -
    -
    - - <%= f.text_field :title, :as => :string, :class => "text_field", :placeholder => t("org_admin.templates.section_title_placeholder")%> -
    - - -
    - -
    -
    -
    - - - - - - - - - -
    <%= t("org_admin.templates.phase_order_label") %> - <%= f.number_field :number, :in => 1..15, :class => "number_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.templates.section_number_help_text") %>
    <%= t("org_admin.templates.desc_label") %> -
    - <%= text_area_tag("section-desc", "" , class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "section_desc_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.templates.section_desc_help_text_html"))%> -
    -
    - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), "#", :id => "", :class => "btn cancel" %> -
    -
    -
    -
    -
    -<%end%> - - diff --git a/app/views/dmptemplates/_add_suggested_answer.html.erb b/app/views/dmptemplates/_add_suggested_answer.html.erb deleted file mode 100644 index 03e11b7..0000000 --- a/app/views/dmptemplates/_add_suggested_answer.html.erb +++ /dev/null @@ -1,25 +0,0 @@ - -<%= form_for :suggested_answer, :url => {:action => "admin_createsuggestedanswer"} do |f| %> - <%= f.hidden_field :organisation_id, :value => current_user.organisation.id %> - <%= f.hidden_field :question_id, :value => question.id %> - - - - - - -
    <%= t("org_admin.questions.suggested_or_example_answer_label")%> -
      -
    • <%= f.select :is_example, {t("org_admin.questions.example_answer_label") => true, t("org_admin.questions.suggested_answer_label") => false} %>
    • -
    • <%= f.text_area :text, :rows => 5 %> -
    • -
    -
    -
    - - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), "#", :id => "cancel_suugested_answer", :class => "btn cancel" %> -
    -<%end%> diff --git a/app/views/dmptemplates/_admin_nav_tabs.html.erb b/app/views/dmptemplates/_admin_nav_tabs.html.erb deleted file mode 100644 index 49c3c20..0000000 --- a/app/views/dmptemplates/_admin_nav_tabs.html.erb +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/app/views/dmptemplates/_edit_guidance.html.erb b/app/views/dmptemplates/_edit_guidance.html.erb deleted file mode 100644 index 8debbca..0000000 --- a/app/views/dmptemplates/_edit_guidance.html.erb +++ /dev/null @@ -1,26 +0,0 @@ - -<%= form_for(suggested_answer, :url => admin_updatesuggestedanswer_dmptemplate_path(suggested_answer), :html => { :method => :put}) do |f| %> - <%= f.hidden_field :organisation_id, :value => current_user.organisation.id %> - - - - - - -
    <%= t("org_admin.questions.suggested_or_example_answer_label")%> -
      -
    • <%= f.select :is_example, {t("org_admin.questions.example_answer_label") => true, t("org_admin.questions.suggested_answer_label") => false} %>
    • -
    • <%= f.text_area :text, :rows => 5 %>
    • -
    -
    -
    - - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.delete"), admin_destroysuggestedanswer_dmptemplate_path(:suggested_answer => suggested_answer.id), - :confirm => t("org_admin.questions.delete_suggested_answer_message", :question_text => question.text ), :method => :delete, :class => "btn btn-primary"%> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t("helpers.submit.cancel"), "#", :class => "btn cancel cancel_edit_suggested_answer" %> -
    -<%end%> diff --git a/app/views/dmptemplates/_edit_phase.html.erb b/app/views/dmptemplates/_edit_phase.html.erb deleted file mode 100644 index 1536a48..0000000 --- a/app/views/dmptemplates/_edit_phase.html.erb +++ /dev/null @@ -1,45 +0,0 @@ - - -<%= form_for(phase, :url => admin_updatephase_dmptemplate_path(phase), :html => { :method => :put}) do |f| %> - -

    - <%= t('org_admin.templates.phase_details_label')%> -

    -
    - <%= raw t('org_admin.templates.phase_details_text_html')%> -
    -
    -
    - - - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= f.text_field :title, - :as => :string, - :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.templates.phase_title_help_text') %>
    <%= t('org_admin.templates.phase_order_label') %><%= f.number_field :number, :in => 0..5, :class => "number_field has-tooltip", 'data-toggle' => "tooltip", 'title' => t('org_admin.templates.phase_number_help_text') %>
    <%= t('org_admin.templates.desc_label') %> -
    - <%= text_area_tag("phase-desc", phase.description, class: "tinymce") %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'phase_desc_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.templates.phase_desc_help_text_html'))%> -
    -
    -
    - - -
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <%= link_to t('helpers.submit.cancel'), admin_phase_dmptemplate_path(phase), :class => 'btn cancel' %> -
    - -<%end%> \ No newline at end of file diff --git a/app/views/dmptemplates/_edit_question.html.erb b/app/views/dmptemplates/_edit_question.html.erb deleted file mode 100644 index ab12c02..0000000 --- a/app/views/dmptemplates/_edit_question.html.erb +++ /dev/null @@ -1,174 +0,0 @@ - - -<%= form_for(question, :url => admin_updatequestion_dmptemplate_path(question), :html => { :method => :put}) do |f| %> -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= t("org_admin.questions.question_number_label")%><%= f.number_field :number, :in => 1..50, :class => "number_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.questions.number_help_text") %> -
    -
    <%= t("org_admin.questions.question_text_label")%><%= f.text_area :text, :rows => "5" %> -
    -
    <%= t("org_admin.questions.answer_format_label")%>
    -
    - <%= f.hidden_field :id,{ :class => "quest_id" } %> - <%= f.select :question_format_id, - options_from_collection_for_select(QuestionFormat.all.order("title"), :id, :title, question.question_format_id), - {}, :id => "#{question.id}-select-format"%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_format_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_format_help_text_html"))%> -
    - -
    - - - -
    - - -
    - - -
    - -
    -
    -
    -
    <%= t("org_admin.questions.suggested_or_example_answer_label")%>
    - <% suggested_answer = question.suggested_answers.find_by_organisation_id(current_user.organisation.id) %> - <% if suggested_answer.nil? then %> - <% suggested_answer = question.suggested_answers.build %> - <%end%> - <%= f.fields_for :suggested_answers, suggested_answer do |s|%> - <%= s.hidden_field :organisation_id, :value => current_user.organisation.id %> -
      -
    • <%= s.select :is_example, {t("org_admin.questions.example_answer_label") => true, t("org_admin.questions.suggested_answer_label") => false} %>
    • -
    • <%= s.text_area :text, :rows => 5 %> -
    • -
    - <%end%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "suggested_answer_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.suggested_answer_help_text_html"))%> -
    -
    -
    -
    <%= t("org_admin.questions.guidance_label")%>
    - <%= text_area_tag("question-guidance-#{question.id}", question.guidance , class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_guidance_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_guidance_help_text_html"))%> -
    -
    -
    -
    <%= t("org_admin.questions.themes_label")%>
    - <%= f.collection_select(:theme_ids, - Theme.all.order("title"), - :id, :title, {:prompt => false, :include_blank => "None"}, {:multiple => true})%> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "question_themes_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.questions.question_themes_help_text_html"))%> -
    -
    -
    - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <% if !question.section.version.published? then%> - <%= link_to t("helpers.submit.delete"), admin_destroyquestion_dmptemplate_path(:question_id => question.id), - :confirm => t("org_admin.questions.delete_message", :question_text => question.text ), :method => :delete, :class => "btn btn-primary"%> - <%end%> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t("helpers.submit.cancel"), "#", :class => "btn cancel cancel_edit_question" %> -
    -
    - - - -<%= render :partial => "guidance_display", locals: {question: question}%> -<%end%> diff --git a/app/views/dmptemplates/_edit_section.html.erb b/app/views/dmptemplates/_edit_section.html.erb deleted file mode 100644 index 8f7f8b4..0000000 --- a/app/views/dmptemplates/_edit_section.html.erb +++ /dev/null @@ -1,116 +0,0 @@ - - - -<%= form_for(section, :url => admin_updatesection_dmptemplate_path(section, :phase => phase, :edit => edit), :html => { :method => :put}) do |s| %> - <%if @open && @section_id == section.id then%> - <% toggle = 'accordion-body section-collapse in collapse'%> - <%else%> - <% toggle = 'accordion-body collapse section-collapse' %> - <%end%> - - <%if @new_sec then%> - <% toggle = 'accordion-body section-collapse in collapse'%> - <%end%> - -
    -
    -
    -
    - <%= s.text_field :title, :as => :string, :class => 'text_field', :placeholder => t('org_admin.templates.section_title_placeholder') %> - -
    -
    - -
    - - -
    -
    - - - - - - - - - -
    <%= t('org_admin.templates.phase_order_label') %><%= s.number_field :number, :in => 1..15, :class => "number_field has-tooltip", 'data-toggle' => "tooltip", 'title' => t('org_admin.templates.section_number_help_text') %>
    <%= t('org_admin.templates.desc_label') %> -
    - <%= text_area_tag("section-desc-#{section.id}", section.description , class: "tinymce") %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'section_desc_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.templates.section_desc_help_text_html'))%> -
    -
    - -
    - <%= s.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <% if !section.version.published? || phase.dmptemplate.org_type == constant("organisation_types.funder") then%> - <%= link_to t("helpers.submit.delete"), admin_destroysection_dmptemplate_path(:section_id => section.id), - :confirm => t("org_admin.templates.section_delete_message", :section_title => section.title ), :method => :delete, :class => "btn btn-primary"%> - <%end%> - <%= link_to t('helpers.submit.cancel'), :back, :class => 'btn cancel' %> -
    - <%end%> -
    - <% @questions = section.questions.order("number")%> - <%if @questions.count > 0 %> - <% question_left = @questions.count %> - <% @questions.each do |question| %> -
    -
    "> - - <%= render :partial => 'show_question', locals: {question: question} %> -
    - - -
    - - <%if question_left.to_i > 1 then %> -
    - <%else%> -
    - <%end%> - <% question_left = question_left - 1 %> - - <%end%> - <%end%> - - - <% if !section.version.published? || phase.dmptemplate.org_type == constant("organisation_types.funder") then%> - - <%if @questions.count != 0 %> -
    - <%end%> - - - - -
    -
    - <%= hidden_field_tag :section_id, section.id, :class => "section_id" %> - <%= link_to t("org_admin.add_question_label"), '#', :class => "btn btn-primary add_question_button" %> -
    -
    - <%end%> - -
    -
    -
    -
    diff --git a/app/views/dmptemplates/_edit_suggested_answer.html.erb b/app/views/dmptemplates/_edit_suggested_answer.html.erb deleted file mode 100644 index 2f78934..0000000 --- a/app/views/dmptemplates/_edit_suggested_answer.html.erb +++ /dev/null @@ -1,26 +0,0 @@ - -<%= form_for(suggested_answer, :url => admin_updatesuggestedanswer_dmptemplate_path(suggested_answer), :html => { :method => :put}) do |f| %> - <%= f.hidden_field :organisation_id, :value => current_user.organisation.id %> - - - - - - -
    <%= t('org_admin.questions.suggested_or_example_answer_label')%> -
      -
    • <%= f.select :is_example, {t('org_admin.questions.example_answer_label') => true, t('org_admin.questions.suggested_answer_label') => false} %>
    • -
    • <%= f.text_area :text, :rows => 5 %>
    • -
    -
    -
    - - -
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <%= link_to t("helpers.submit.delete"), admin_destroysuggestedanswer_dmptemplate_path(:suggested_answer => suggested_answer.id), - :confirm => t("org_admin.questions.delete_suggested_answer_message", :question_text => question.text ), :method => :delete, :class => "btn btn-primary"%> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t('helpers.submit.cancel'), '#', :class => 'btn cancel cancel_edit_suggested_answer' %> -
    -<%end%> diff --git a/app/views/dmptemplates/_edit_template.html.erb b/app/views/dmptemplates/_edit_template.html.erb deleted file mode 100644 index dbea10a..0000000 --- a/app/views/dmptemplates/_edit_template.html.erb +++ /dev/null @@ -1,52 +0,0 @@ - - -<%= form_for(dmptemplate, :url => admin_update_dmptemplate_path(dmptemplate), :html => { :method => :put}) do |f| %> -
    - - - - - - - - - - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= f.text_field :title, :as => :string, - :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.templates.title_help_text') %>
    <%= t('org_admin.templates.desc_label') %>
    - <%= text_area_tag("template-desc", dmptemplate.description, class: "tinymce") %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'template_desc_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.templates.desc_help_text_html'))%> -
    -
    <%= t('org_admin.templates.published_label') %><%if dmptemplate.published? || dmptemplate.has_published_versions? then%> - <%= f.check_box :published, :as => :check_boxes %> - <%else%> - <%= t('org_admin.templates.cannot_publish')%> - <%end%> -
    <%= t('org_admin.templates.created') %> - <%= l dmptemplate.created_at.to_date, :formats => :short %> -
    <%= t('org_admin.templates.last_updated') %> - <%= l dmptemplate.updated_at.to_date, :formats => :short %> -
    - - -
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <%= link_to t('helpers.submit.cancel'), admin_template_dmptemplate_path(dmptemplate), :class => 'btn cancel' %> -
    - -
    - -<%end%> \ No newline at end of file diff --git a/app/views/dmptemplates/_edit_version.html.erb b/app/views/dmptemplates/_edit_version.html.erb deleted file mode 100644 index 416fdb7..0000000 --- a/app/views/dmptemplates/_edit_version.html.erb +++ /dev/null @@ -1,47 +0,0 @@ - - - -<%= form_for(version, :url => admin_updateversion_dmptemplate_path(version, :edit => edit, :phase => phase), :html => { :method => :put}) do |f| %> - -

    - <%= t('org_admin.templates.version_details_label')%> -

    -
    - -
    - - - - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= f.text_field :title, :as => :string, - :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.templates.phase_title_help_text') %>
    <%= t('org_admin.templates.desc_label') %>
    - <%= text_area_tag("version-desc", version.description, class: "tinymce") %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'version_desc_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.versions.desc_help_text_html'))%> -
    -
    <%= t('org_admin.templates.published_label') %><%= f.check_box :published, :as => :check_boxes %>
    - -
    - -
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <%= link_to t('helpers.submit.cancel'), admin_phase_dmptemplate_path(phase), :class => 'btn cancel' %> -
    -
    - -<%end%> - - - \ No newline at end of file diff --git a/app/views/dmptemplates/_guidance_display.html.erb b/app/views/dmptemplates/_guidance_display.html.erb deleted file mode 100644 index 4082baf..0000000 --- a/app/views/dmptemplates/_guidance_display.html.erb +++ /dev/null @@ -1,36 +0,0 @@ - - -
    -
    - <% if !question.guidance.nil? && question.guidance != "" then %> - - <% end %> - - <% question.guidance_for_question(question, current_user.organisation).each_pair do |title,guidance| %> -
    - -
    -
    <%= raw guidance.text %>
    -
    -
    - <% end %> -
    - -
    \ No newline at end of file diff --git a/app/views/dmptemplates/_option_fields.html.erb b/app/views/dmptemplates/_option_fields.html.erb deleted file mode 100644 index 21f3e80..0000000 --- a/app/views/dmptemplates/_option_fields.html.erb +++ /dev/null @@ -1,7 +0,0 @@ - - - <%= f.number_field :number,:in => 1..20, :class => "number_field option"%> - <%= f.text_field :text, :as => :string, :class => "small_text_field" %> - <%= f.check_box :is_default %> - <%= f.hidden_field :_destroy %><%= t('org_admin.remove_option_label') %> - diff --git a/app/views/dmptemplates/_preview_question.html.erb b/app/views/dmptemplates/_preview_question.html.erb deleted file mode 100644 index fa75e30..0000000 --- a/app/views/dmptemplates/_preview_question.html.erb +++ /dev/null @@ -1,124 +0,0 @@ - - -
    - - - <% q_format = question.question_format%> -
    -
    - - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> - <% options = question.options.order("number") %> - - - <% if q_format.title == t("helpers.checkbox") then %> - <%if !options.nil? then %> -
    - -
      - <% options.each do |op|%> -
    1. - <%end%> -
    -
    - <%end%> - - <% elsif q_format.title == t("helpers.multi_select_box") then %> - <%if !options.nil? then %> - - - <%end%> - - <% elsif q_format.title == t("helpers.radio_buttons") then%> - <%if !options.nil? then %> -
    - -
      - <% options.each do |op|%> -
    1. - <%end%> -
    -
    - <%end%> - - <% elsif q_format.title == t("helpers.dropdown") then%> - <%if !options.nil? then %> - - - <%end%> - <% end %> - - - <% suggested_answer = question.suggested_answers.find_by_organisation_id(current_user.organisation_id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> -
    - - <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> - <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> - <%end%> - -
    -

    - <%= raw suggested_answer.text %> -

    -
    -
    - <% end %> - -
    - - <% else %> - - - <% suggested_answer = question.suggested_answers.find_by_organisation_id(current_user.organisation_id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> -
    - - <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> - <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> - <%end%> - -
    -

    - <%= raw suggested_answer.text %> -

    -
    -
    - <% end %> - - <% end %> - - - - - <% if q_format.title == t("helpers.text_field") then %> - - - <%elsif q_format.title == t("helpers.text_area") then%> - - <%end%> -
    - - <%= link_to t("helpers.save"), "#", :class => "btn btn-primary", :onclick => "event.preventDefault();" %> - - <%= t("helpers.notanswered") %> - -
    -
    -
    - - - -<%= render :partial => "guidance_display", locals: {question: question}%> diff --git a/app/views/dmptemplates/_show_phase.html.erb b/app/views/dmptemplates/_show_phase.html.erb deleted file mode 100644 index 01117cf..0000000 --- a/app/views/dmptemplates/_show_phase.html.erb +++ /dev/null @@ -1,37 +0,0 @@ - - -

    - <%= t('org_admin.templates.phase_details_label')%> - - - <% if @phase.dmptemplate.org_type != constant("organisation_types.funder") || current_user.org_type == constant("organisation_types.funder") then %> -
    - <%= link_to t("org_admin.templates.edit_phase_details_label"), '#', :class => "btn btn-primary", :id => "edit_phase_button"%> -
    - <%end%> -

    - -<%if @phase.dmptemplate.org_type != constant("organisation_types.funder") then%> -
    - <%= raw t('org_admin.templates.phase_details_text_html')%> -
    -<%end%> - -
    -
    - - - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= @phase.title %>
    <%= t('org_admin.templates.phase_order_label') %><%= @phase.number %>
    <%= t('org_admin.templates.desc_label') %><%= raw @phase.description %>
    -
    diff --git a/app/views/dmptemplates/_show_phases_sections.html.erb b/app/views/dmptemplates/_show_phases_sections.html.erb deleted file mode 100644 index 19c603a..0000000 --- a/app/views/dmptemplates/_show_phases_sections.html.erb +++ /dev/null @@ -1,73 +0,0 @@ - - -
    - -
    -

    <%= raw phase.description %>

    -
    - -<% if phase.versions.any? then %> - - <% version = phase.versions.where("published = ?", true).first %> - <% if version.nil? then%> - <% version = phase.versions.order("updated_at DESC").first %> - <%end%> - - -
    - - - <%if phase.has_sections == true then %> - <%= link_to t("helpers.preview"), admin_previewphase_dmptemplate_path(version), :class => 'btn btn-primary'%> - <%end%> - <% if phase.latest_published_version == nil then%> - <%= link_to t("helpers.submit.delete"), admin_destroyphase_dmptemplate_path(:phase_id => phase.id), - :confirm => t("org_admin.templates.phase_delete_message", :phase_title => phase.title ), :method => :delete, :class => "btn btn-primary"%> - <%end%> - <%if phase.dmptemplate.org_type == constant("organisation_types.funder") && current_user.org_type != constant("organisation_types.funder") then%> - <% b_label = t('org_admin.templates.view_phase_label')%> - <%else %> - <% b_label = t('org_admin.templates.edit_phase_label')%> - <%end%> - <%= link_to b_label, admin_phase_dmptemplate_path(phase), :class => "btn btn-primary" %> - -
    - <% if version.sections.any? then %> - - - - - - - - - <% version.sections.order("number ASC").each do |section| %> - <%if (section.organisation_id == phase.dmptemplate.organisation_id ) || ( section.organisation_id == current_user.organisation_id) then%> - - - - - <%end%> - <%end%> - -
    <%= t('helpers.sections_label')%><%= t('helpers.questions_label')%>
    -

    <%= section.title %>

    -
    - <% if section.questions.any? %> - <% questions = section.questions.order("number ASC") %> -
      - <% questions.each do |ques|%> -
    • - - <%= raw ques.text %> -
    • - <%end%> -
    - <%end%> -
    - - <%end%> - -<%end%> - - -
    diff --git a/app/views/dmptemplates/_show_question.html.erb b/app/views/dmptemplates/_show_question.html.erb deleted file mode 100644 index df79c2b..0000000 --- a/app/views/dmptemplates/_show_question.html.erb +++ /dev/null @@ -1,153 +0,0 @@ - - -
    - - - - - - - - - - - - - - <%if q_format.title == t("helpers.text_field") || q_format.title == t("helpers.text_area") then %> - <%if !question.default_value.nil? then %> - - - - - <%end%> - <% end %> - - - - - - - - <% if (question.section.version.phase.dmptemplate.org_type != constant("organisation_types.funder") && question.section.organisation_id == current_user.organisation_id ) then%> - <% suggested_answer = question.get_suggested_answer(current_user.organisation.id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> - - - - - <%end%> - <%end%> - - <%if !question.guidance.nil? then %> - - - - - <%end%> - - <% themes_q = question.themes %> - <%if !themes_q.nil? then%> - - - - - <%end%> -
    <%= t('org_admin.questions.question_number_label')%><%= question.number%>
    <%= t('org_admin.questions.question_text_label')%><%= raw question.text %> -
    -
    - <% q_format = question.question_format %> - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> -
      - <% if question.options.is_a? Option then %> -
    • - <%= question.options.text %>
    • - <% else %> - <% if !question.options.to_a.nil? then %> - <% question.options.to_a.sort_by{|op| op['number']}.each do |o| %> -
    • - <%= o.text %>
    • - <%end%> - <% end %> - <% end %> -
    - <% end %> -
    -
    <%= t('org_admin.questions.default_value_label')%><%= raw question.default_value %>
    <%= t('org_admin.questions.answer_format_label')%><%= q_format.title %> -
    - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> - <% if question.option_comment_display == true then%> - <%= t("org_admin.questions.option_comment_display")%> - <%else%> - <%= t("org_admin.questions.option_comment_hide")%> - <%end%> - <%end%> -
    -
    - <% if suggested_answer.is_example? then %> - <%= t('org_admin.questions.example_answer_label')%> - <%else%> - <%= t('org_admin.questions.suggested_answer_label')%> - <%end%> - <%= raw suggested_answer.text %>
    <%= t('org_admin.questions.guidance_label')%><%= raw question.guidance %>
    <%= t('org_admin.questions.themes_label')%><% i = 1%> - <% themes_q.each do |t|%> - <%= t.title %> - <% if themes_q.count > i then%> - , - <% i +=1 %> - <% end %> - <%end%> -
    -
    - - <% if (question.section.version.phase.dmptemplate.org_type == constant("organisation_types.funder") && question.section.organisation_id != current_user.organisation_id ) then%> - <% suggested_answer = question.get_suggested_answer(current_user.organisation.id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> -
    - <%= render :partial => 'show_suggested_answer', locals: {suggested_answer: suggested_answer, question: question} %> -
    - - - <%end%> - - - - - - <%end%> - -
    - - <%if (@edit == 'true'&& question.section.organisation_id == current_user.organisation_id) || (question.section.version.phase.dmptemplate.org_type == constant("organisation_types.funder") && question.section.organisation_id == current_user.organisation_id && current_user.org_type != constant("organisation_types.funder")) then%> -
    - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t("org_admin.questions.question_edit_button"), '# ', :class => "btn btn-primary edit_question_button"%> - <% if !question.section.version.published? then%> - <%= link_to t("org_admin.questions.question_delete_button"), admin_destroyquestion_dmptemplate_path(:question_id => question.id), - :confirm => t("org_admin.questions.delete_message", :question_text => question.text ), :method => :delete, :class => "btn btn-primary"%> - <%end%> -
    - <%elsif (@edit == 'false' && question.section.organisation_id != current_user.organisation_id )|| (question.section.version.phase.dmptemplate.org_type == constant("organisation_types.funder") && question.section.organisation_id != current_user.organisation_id ) then%> - <% suggested_answer = question.get_suggested_answer(current_user.organisation.id) %> - <% if suggested_answer.nil? then %> -
    -
    - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t("org_admin.questions.suggested_or_example_answer_button"), '# ', :class => "btn btn-primary add_suggested_answer_button"%> -
    -
    - <%end%> - <%end%> -
    -
    - - - -<%= render :partial => 'guidance_display', locals: {question: question}%> diff --git a/app/views/dmptemplates/_show_section.html.erb b/app/views/dmptemplates/_show_section.html.erb deleted file mode 100644 index 1dbf719..0000000 --- a/app/views/dmptemplates/_show_section.html.erb +++ /dev/null @@ -1,43 +0,0 @@ - -<%if @open && @section_id == section.id then%> - <% toggle = 'accordion-body section-collapse in collapse'%> -<%else%> - <% toggle = 'accordion-body collapse section-collapse' %> -<%end%> -
    - -
    -
    - <%= raw section.description %> -
    -
    - <% section.questions.order("number").each do |question| %> - <% last_question_id = section.questions.order("number DESC").first.id %> - -
    - - <%= render :partial => 'show_question', locals: {question: question}%> -
    - - <% if last_question_id == question.id then %> -
    - <% else %> -
    - <% end %> - - <%end%> -
    -
    -
    diff --git a/app/views/dmptemplates/_show_suggested_answer.html.erb b/app/views/dmptemplates/_show_suggested_answer.html.erb deleted file mode 100644 index 888dd45..0000000 --- a/app/views/dmptemplates/_show_suggested_answer.html.erb +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -
    - <% if suggested_answer.is_example? then %> - <%= t('org_admin.questions.example_answer_label')%> - <%else%> - <%= t('org_admin.questions.suggested_answer_label')%> - <%end%> - <%= raw suggested_answer.text %>
    -
    - -
    - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= link_to t("org_admin.questions.edit_suggested_answer_button"), '# ', :class => "btn btn-primary edit_form_for_suggested_answer"%> -
    diff --git a/app/views/dmptemplates/_show_template.html.erb b/app/views/dmptemplates/_show_template.html.erb deleted file mode 100644 index 7cfec9d..0000000 --- a/app/views/dmptemplates/_show_template.html.erb +++ /dev/null @@ -1,43 +0,0 @@ - - -<% if @dmptemplate.org_type != constant("organisation_types.funder") || current_user.org_type == constant("organisation_types.funder") then %> -

    -
    - <%= link_to t("org_admin.templates.edit_details"), '# ', :class => "btn btn-primary", :id => "edit_template_button"%> -
    -

    -<%end%> -
    - - - - - - - - - - - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= dmptemplate.title %>
    <%= t('org_admin.templates.desc_label') %><% if !dmptemplate.description.nil? && dmptemplate.description != "" then %> - <%= raw dmptemplate.description %> - <%else%> - - - <%end%> -
    <%= t('org_admin.templates.published_label') %><%if dmptemplate.published || dmptemplate.has_published_versions? then%> - <%= dmptemplate.published %> - <%else%> - <%= t('org_admin.templates.cannot_publish')%> - <%end%> -
    <%= t('org_admin.templates.created') %><%= l dmptemplate.created_at.to_date, :formats => :short %>
    <%= t('org_admin.templates.last_updated') %><%= l dmptemplate.updated_at.to_date, :formats => :short %>
    diff --git a/app/views/dmptemplates/_show_version.html.erb b/app/views/dmptemplates/_show_version.html.erb deleted file mode 100644 index 3e1456e..0000000 --- a/app/views/dmptemplates/_show_version.html.erb +++ /dev/null @@ -1,42 +0,0 @@ - - - -

    - <%= t('org_admin.templates.version_details_label')%> -

    -
    - - - - - - - <% if version.description != "" then%> - - - - - <%end%> - - - - - - - - - - - - -
    <%= t('org_admin.templates.title_label') %><%= version.title %>
    <%= t('org_admin.templates.desc_label') %><%= raw version.description %>
    <%= t('org_admin.templates.published_label') %><%= version.published %>
    <%= t('org_admin.templates.created') %> - <%= l version.created_at.to_date, :formats => :short %> -
    <%= t('org_admin.templates.last_updated') %> - <%= l version.updated_at.to_date, :formats => :short %> -
    -
    - - - - - diff --git a/app/views/dmptemplates/_versions_table.html.erb b/app/views/dmptemplates/_versions_table.html.erb deleted file mode 100644 index e51dbfe..0000000 --- a/app/views/dmptemplates/_versions_table.html.erb +++ /dev/null @@ -1,73 +0,0 @@ -<%if !phase.versions.nil? then %> -
    -

    <%= t('org_admin.templates.versions_label')%>

    -

    - <%= t('org_admin.versions.versions_text_html')%> -

    - - - - - - - - - - - - - - <% phase.versions.each do |v|%> - - - - - - - - - - - - - <%end%> - -
    <%= t('org_admin.templates.title_label')%><%= t('org_admin.templates.published_label')%><%= t('org_admin.templates.created')%><%= t('org_admin.templates.last_updated') %><%= t('org_admin.templates.actions') %>
    - <%= v.title %> - - <%= v.published %> - - <%= l v.created_at.to_date, :formats => :short %> - - <%= l v.updated_at.to_date, :formats => :short %> - - <%= link_to t("helpers.view"), admin_phase_dmptemplate_path( :version_id => v.id, :id => phase.id , :edit => 'false'), :class => "dmp_table_link"%> - <% if v.published? then%> - - <%= t('org_admin.versions.edit_label')%> - - <%= link_to t("helpers.preview"), admin_previewphase_dmptemplate_path(v), :class => "dmp_table_link" %> - <%else%> - <%= link_to t("org_admin.versions.edit_label"), admin_phase_dmptemplate_path(phase, :version_id => v.id, :edit => 'true'), :class => "dmp_table_link" %> - <%= link_to t("helpers.preview"), admin_previewphase_dmptemplate_path(v), :class => "dmp_table_link" %> - <%#= link_to t("helpers.submit.delete"), admin_destroyversion_dmptemplate_path(:version_id => v.id, :phase => phase , :edit => 'false'), - :confirm => t("org_admin.versions.delete_message", :version_title => v.title ), :method => :delete, :class => "dmp_table_link"%> - <%end%> -
    -
    - - - -<%end%> diff --git a/app/views/dmptemplates/admin_addphase.html.erb b/app/views/dmptemplates/admin_addphase.html.erb deleted file mode 100644 index 6e8a336..0000000 --- a/app/views/dmptemplates/admin_addphase.html.erb +++ /dev/null @@ -1,75 +0,0 @@ -<%- model_class = Phase -%> -<%= stylesheet_link_tag "admin" %> -<% javascript "admin.js" %> - -

    - <%= @dmptemplate.title %> - -
    - <%= link_to t("org_admin.templates.view_all_templates"), - admin_index_dmptemplate_path, - :class => "btn btn-primary" %> -
    -

    - -
    - - -<%= render :partial => "admin_nav_tabs", locals: {dmptemplate: @dmptemplate, active: "add_plan"} %> - - -
    -
    - - -
    -
    - - - <%= form_for :phase, :url => { :action => "admin_createphase"} do |f| %> -

    - <%= t("org_admin.templates.phase_details_label")%> -

    - <%= raw t("org_admin.templates.phase_new_text_html")%> -
    -
    - <%= f.hidden_field :dmptemplate_id, :value => @dmptemplate.id%> - - - - - - - - - - - - - -
    <%= t("org_admin.templates.title_label") %><%= f.text_field :title, - :as => :string, - :class => "text_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.templates.phase_title_help_text") %>
    <%= t("org_admin.templates.phase_order_label") %><%= f.number_field :number, :in => 1..5, :class => "number_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.templates.phase_number_help_text") %>
    <%= t("org_admin.templates.desc_label") %> -
    - <%= text_area_tag("phase-desc","" , class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "phase_desc_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.templates.phase_desc_help_text_html"))%> -
    -
    -
    -
    - - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), admin_dmptemplate_path(@dmptemplate), :class => "btn cancel" %> -
    - - <%end%> -
    -
    -
    -
    - -<%= tinymce :content_css => asset_path("application.css") %> \ No newline at end of file diff --git a/app/views/dmptemplates/admin_index.html.erb b/app/views/dmptemplates/admin_index.html.erb deleted file mode 100644 index b22018c..0000000 --- a/app/views/dmptemplates/admin_index.html.erb +++ /dev/null @@ -1,153 +0,0 @@ -<%= stylesheet_link_tag "admin" %> - -

    - <%= t('org_admin.templates_label') %> -

    -
    -

    - <%= t('org_admin.templates.own_temp') %> -

    - -
    - <%= raw t('org_admin.templates.create_own_template_text_html')%> -
    -
    - -
    - <%= link_to t("org_admin.templates.create_template"), - admin_new_dmptemplate_path, - :class => 'btn btn-primary' %> -
    -
    -
    - - -<% if @dmptemplates_own.count > 0 then %> - - - - - - - - - - - - <% @dmptemplates_own.each do |org_template| %> - - - - - - - - - <%end%> - -
    <%= t('org_admin.templates.title_label') %><%= t('org_admin.templates.desc_label') %><%= t('org_admin.templates.published_label') %><%= t('org_admin.templates.last_updated') %><%= t('org_admin.templates.actions') %>
    - <%= org_template.title%> - - <%= raw org_template.description.truncate(90, omission: t('helpers.truncate_continued')) %> - - <%= org_template.published %> - - <% last_temp_updated = org_template.updated_at %> - <% org_template.phases.each do |phase|%> - <% if phase.versions.any? then%> - <% phase.versions.each do |version| %> - <% if org_template.updated_at.to_date < version.updated_at.to_date then %> - <% last_temp_updated = version.updated_at %> - <%end%> - <%end%> - <%end%> - <%end%> - <%= l last_temp_updated.to_date, :formats => :short %> - - <%if current_user.can_org_admin? then%> - <% b_label = t('helpers.submit.edit')%> - <%else%> - <% b_label = t('helpers.view')%> - <%end%> - <%= link_to b_label, admin_template_dmptemplate_path(org_template), :class => "dmp_table_link"%> -
    - -<%end%> - -
    -
    - - -<% if current_user.org_type != constant("organisation_types.funder") then %> -

    - <%= t("org_admin.templates.funders_temp") %> -

    - - - <% if @dmptemplates_funders.count > 0 then %> - - - - - - - - - - - - - - <% @dmptemplates_funders.each do |org_template| %> - <% if org_template.published? ||org_template.has_customisations?(current_user.organisation_id, org_template) then %> - - - - - - - - <%end%> - <%end%> - -
    <%= t('org_admin.templates.title_label') %><%= t('org_admin.templates.desc_label') %><%= t('org_admin.templates.published_label') %><%= t('org_admin.templates.last_updated') %><%= t('org_admin.templates.actions') %>
    - <%= org_template.title%> - - <%= raw org_template.description.truncate(90, omission: t('helpers.truncate_continued')) %> - - <%if org_template.published? then %> - <%= org_template.published%> - <%else%> - <%= t("helpers.false_lowercase")%> - <%end%> - - <% last_updated = org_template.updated_at %> - <% org_template.phases.each do |phase|%> - <% if phase.versions.any? then%> - <% phase.versions.each do |version| %> - <% if org_template.updated_at.to_date < version.updated_at.to_date then %> - <% last_updated = version.updated_at %> - <%end%> - <%end%> - <%end%> - <%end%> - <%= l last_updated.to_date, :formats => :short %> - - - <%if current_user.can_org_admin? then%> - <% if org_template.org_type == constant("organisation_types.funder") then %> - <%if org_template.has_customisations?(current_user.organisation_id, org_template) then%> - <% b_label = t("org_admin.templates.edit_customisation")%> - <%else%> - <% b_label = t("org_admin.templates.customise")%> - <%end%> - <%else%> - <% b_label = t("helpers.submit.edit")%> - <%end%> - <%else%> - <% b_label = t("helpers.view")%> - <%end%> - <%= link_to b_label, admin_template_dmptemplate_path(org_template), :class => "dmp_table_link"%> -
    - <%end%> -<%end%> diff --git a/app/views/dmptemplates/admin_new.html.erb b/app/views/dmptemplates/admin_new.html.erb deleted file mode 100644 index 798f855..0000000 --- a/app/views/dmptemplates/admin_new.html.erb +++ /dev/null @@ -1,48 +0,0 @@ -<%= stylesheet_link_tag "admin" %> -<% javascript "admin.js" %> - -

    - <%= t("org_admin.templates.new_label") %> - -
    - <%= link_to t("org_admin.templates.view_all_templates"), - admin_index_dmptemplate_path, - :class => "btn btn-primary" %> -
    -

    - -
    -
    - -
    - <%= raw t("org_admin.templates.create_new_template_text_html")%> -
    - <%= form_for :dmptemplate, :url => {:action => "admin_create"} do |f| %> - - - - - - - - - - -
    <%= t("org_admin.templates.title_label") %><%= f.text_field :title, :as => :string, - :class => "text_field has-tooltip", "data-toggle" => "tooltip", "title" => t("org_admin.templates.title_help_text") %>
    <%= t("org_admin.templates.desc_label") %>
    - <%= text_area_tag("template-desc", "", class: "tinymce") %> -
    -
    - <%= link_to( image_tag("help_button.png"), "#", :class => "template_desc_popover", :rel => "popover", "data-html" => "true", "data-content" => t("org_admin.template_desc_help_text_html"))%> -
    -
    - -
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), admin_index_dmptemplate_path, :class => "btn cancel" %> -
    -
    - <%end%> -
    -
    -<%= tinymce :content_css => asset_path("application.css") %> \ No newline at end of file diff --git a/app/views/dmptemplates/admin_phase.html.erb b/app/views/dmptemplates/admin_phase.html.erb deleted file mode 100644 index b85927b..0000000 --- a/app/views/dmptemplates/admin_phase.html.erb +++ /dev/null @@ -1,82 +0,0 @@ -<%- model_class = Phase -%> -<%= stylesheet_link_tag "admin" %> -<% javascript 'admin.js' %> - -<%= tinymce :content_css => asset_path('application.css') %> - -

    - <%= @phase.dmptemplate.title %> - -
    - <%= link_to t("org_admin.templates.view_all_templates"), - admin_index_dmptemplate_path, - :class => 'btn btn-primary' %> -
    -

    - -
    - - -<%= render :partial => "admin_nav_tabs", locals: {dmptemplate: @phase.dmptemplate, active: @phase.id} %> - - -
    -
    - - -
    -
    - - -
    - <%= render :partial => "show_phase", locals: {phase: @phase}%> -
    - <% if @phase.dmptemplate.org_type != constant("organisation_types.funder") || current_user.org_type == constant("organisation_types.funder") then %> - - - - <%= render :partial => "versions_table", locals: {phase: @phase}%> - <%end%> - - - <% if @edit == "false" || (@phase.dmptemplate.org_type == constant("organisation_types.funder") && current_user.org_type != constant("organisation_types.funder")) then%> - <%= render :partial => 'show_version', locals: {version: @version}%> - <%elsif @edit == "true" || current_user.org_type == constant("organisation_types.funder") then %> - <%= render :partial => 'edit_version', locals: {version: @version, edit: @edit, phase: @phase} %> - <%end%> -
    -
    - - - <% @sections.order("number ASC").each do |section| %> - <%if (@edit == "true" && section.organisation_id == current_user.organisation_id) || - (@phase.dmptemplate.org_type == constant("organisation_types.funder") && section.organisation_id == current_user.organisation_id && current_user.org_type != constant("organisation_types.funder"))then%> - <%= render :partial => 'edit_section', locals: {section: section, edit: @edit, phase: @phase, version: @version} %> - <%elsif (section.organisation_id == @phase.dmptemplate.organisation_id ) || ( section.organisation_id == current_user.organisation_id) then%> - <%= render :partial => 'show_section', locals: {section: section}%> - <%end%> - <% end %> - -
    -
    - - - - <% if !@version.published? || (@phase.dmptemplate.org_type == constant("organisation_types.funder") && current_user.org_type != constant("organisation_types.funder"))then %> - - - - - -
    -
    - <%= link_to t('org_admin.add_section_label'),'#', :id => 'add_section_button', :class =>'btn btn-primary' %> -
    -
    - <%end%> - - diff --git a/app/views/dmptemplates/admin_previewphase.html.erb b/app/views/dmptemplates/admin_previewphase.html.erb deleted file mode 100644 index 12c2507..0000000 --- a/app/views/dmptemplates/admin_previewphase.html.erb +++ /dev/null @@ -1,64 +0,0 @@ -<%- model_class = Phase -%> -<%= stylesheet_link_tag "admin" %> - -

    - <%= @version.phase.dmptemplate.title %> - -
    - <%= link_to t("org_admin.templates.back_to_edit_phase_label"), - admin_phase_dmptemplate_path(:id => @version.phase_id, :version_id => @version.id, :edit => "true"), - :class => 'btn btn-primary' %> - <%= link_to t("org_admin.templates.view_all_templates"), - admin_index_dmptemplate_path, - :class => 'btn btn-primary' %> -
    -

    - -
    - - -<%= render :partial => "admin_nav_tabs", locals: {dmptemplate: @version.phase.dmptemplate, active: @version.phase_id} %> - - -
    -
    - <% sections = @version.sections %> - <% sections.order(:number).each do |section| %> - <%if (section.organisation_id == @version.phase.dmptemplate.organisation_id ) || ( section.organisation_id == current_user.organisation_id) then%> - -
    - -
    -
    - <%= raw section.description %> -
    -
    - <% section.questions.order("number").each do |question| %> - <% last_question_id = section.questions.order("number DESC").first.id%> - - - <%= render :partial => 'preview_question', locals: {question: question}%> - - <% if last_question_id == question.id then %> -
    - <% else %> -
    - <% end %> - - <%end%> -
    -
    -
    - <%end%> - <%end%> -
    -
    \ No newline at end of file diff --git a/app/views/dmptemplates/admin_template.html.erb b/app/views/dmptemplates/admin_template.html.erb deleted file mode 100644 index 642fb15..0000000 --- a/app/views/dmptemplates/admin_template.html.erb +++ /dev/null @@ -1,61 +0,0 @@ -<%= stylesheet_link_tag "admin" %> -<% javascript 'admin.js' %> - -

    - <%= @dmptemplate.title %> - -
    - <%= link_to t("org_admin.templates.view_all_templates"), - admin_index_dmptemplate_path, - :class => 'btn btn-primary' %> -
    -

    - -
    - - -<%= render :partial => "admin_nav_tabs", locals: {dmptemplate: @dmptemplate, active: "show_template"} %> - - -
    -
    - <% if @dmptemplate.org_type != constant("organisation_types.funder") || current_user.org_type == constant("organisation_types.funder") then %> - - <%end%> -
    - <%= render :partial => "show_template", locals: {dmptemplate: @dmptemplate}%> -
    -
    - - <% if !@dmptemplate.phases.nil? then %> - <% if @dmptemplate.phases.count == 1 then %> - <% @dmptemplate.phases.each do |phase| %> - - <%= render :partial => 'show_phases_sections', locals: {phase: phase}%> - <%end%> - <%else%> - <% @dmptemplate.phases.order(:number).each do |phase| %> -
    -
    - -
    -
    - - <%= render :partial => 'show_phases_sections', locals: {phase: phase}%> -
    -
    -
    -
    - <%end%> - <%end%> - <%end%> -
    - -<%= tinymce :content_css => asset_path('application.css') %> diff --git a/app/views/dmptemplates/export.pdf.erb b/app/views/dmptemplates/export.pdf.erb deleted file mode 100644 index 3726b39..0000000 --- a/app/views/dmptemplates/export.pdf.erb +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - <%= @template.title %> - - - - -

    <%= @template.title %>

    - - \ No newline at end of file diff --git a/app/views/guidance_groups/admin_edit.html.erb b/app/views/guidance_groups/admin_edit.html.erb index 2ea27f8..77146d5 100644 --- a/app/views/guidance_groups/admin_edit.html.erb +++ b/app/views/guidance_groups/admin_edit.html.erb @@ -2,12 +2,12 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance.guidance_group_label') %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => 'btn btn-primary' %> + class: 'btn btn-primary' %>

    @@ -16,65 +16,46 @@
    - <%= form_for(@guidance_group, :url => admin_update_guidance_group_path(@guidance_group), :html => {:method => :put}) do |f| %> + <%= form_for(@guidance_group, url: admin_update_guidance_group_path(@guidance_group), html: {method: :put}) do |f| %> - + - - - - <% if @guidance_group.published == true then %> - + <% end %> - + @@ -84,14 +65,14 @@
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> + <%= f.submit _('Save'), class: 'btn btn-primary' %> <% if @guidance_group.published == false then %> - <%= f.submit t('helpers.submit.publish'), :name => "save_publish", :class => "btn btn-primary" %> + <%= f.submit _('Publish'), name: "save_publish", class: "btn btn-primary" %> <% end %> - <%= link_to t('helpers.submit.cancel'), :back, :class => 'btn cancel' %> + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>

    <% end %> - + diff --git a/app/views/guidance_groups/admin_new.html.erb b/app/views/guidance_groups/admin_new.html.erb index 4bd3367..8ea92b8 100644 --- a/app/views/guidance_groups/admin_new.html.erb +++ b/app/views/guidance_groups/admin_new.html.erb @@ -2,13 +2,13 @@ <% javascript 'admin.js' %>

    - <%= t("org_admin.guidance.guidance_group_label") %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => "btn btn-primary" %> -
    + class: "btn btn-primary" %> +

    @@ -16,56 +16,37 @@
    - <%= form_for :guidance_group, :url => {:action => "admin_create"} do |f| %> - + <%= form_for :guidance_group, url: {action: "admin_create"} do |f| %> +
    <%= t('org_admin.guidance_group.name_label') %><%= _('Name') %>
    <%= f.text_field :name, - :as => :string, - :class => 'text_field' %> + as: :string, + class: 'text_field' %>
    - <%= link_to(image_tag('help_button.png'), '#', :class => 'guidance_group_title_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.title_help_text_html')) %> + <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. "[guidance group name]: guidance on data sharing" so we suggest you just use the institution or department name.')) %>
    <%= t('org_admin.guidance.template') %> -
    - <% if @guidance_group.dmptemplate_ids == [] then %> - <% default_select = "" %> - <% else %> - <% default_select = @guidance_group.dmptemplate_ids %> - <% end %> - <%= f.select :dmptemplate_ids, options_for_select( - [['All templates', ""]].concat(Dmptemplate.funders_and_own_templates(current_user.organisation_id).collect { |g| [g.title, g.id] }), :selected => default_select), {}, - {:prompt => false, :multiple => true} %> -
    -
    - <%= link_to(image_tag('help_button.png'), '#', :class => 'guidance_group_template_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.template_help_text_html')) %> -
    - -
    <%= t('org_admin.templates.published_label') %><%= _('Published') %>
    <%= f.check_box :published %>
    - +
    <%= t('org_admin.guidance_group.subset') %><%= _('Optional subset') %>
    - <%= f.check_box :optional_subset %> <%= t('org_admin.guidance_group.subset_eg') %> + <%= f.check_box :optional_subset %> <%= _('e.g. School/ Department') %>
    - <%= link_to(image_tag('help_button.png'), '#', :class => 'guidance_group_subset_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.subset_option_help_text')) %> + <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard.")) %>
    - + - - - - - + -
    <%= t('org_admin.guidance_group.name_label') %><%= _('Name') %>
    - <%= f.text_field :name, - :as => :string, - :class => "text_field" %> + <%= f.text_field :name, as: :string, class: "text_field" %>
    - <%= link_to( image_tag("help_button.png"), "#", :class => 'guidance_group_title_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t("org_admin.guidance_group.title_help_text_html"))%> -
    - -
    <%= t("org_admin.guidance.template") %>
    - <%= f.select :dmptemplate_ids, options_for_select( - [['All templates', ""]].concat( Dmptemplate.funders_and_own_templates(current_user.organisation_id).collect{ |g| [g.title, g.id] })),{} , - {:prompt => false , :multiple => true}%> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_group_template_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.template_help_text_html'))%> + <%= link_to( image_tag("help_button.png"), "#", class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. "[guidance group name]: guidance on data sharing" so we suggest you just use the institution or department name.'))%>
    <%= t('org_admin.guidance_group.subset') %><%= _('Optional subset') %>
    - <%= f.check_box :optional_subset %> <%= t('org_admin.guidance_group.subset_eg') %> + <%= f.check_box :optional_subset %> <%= _('e.g. School/ Department') %>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_group_subset_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.subset_option_help_text'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard."))%>
    -
    - + -
    - <%= f.submit t("helpers.submit.save"), :name => "draft", :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), :back, :class => "btn cancel btn-secondary" %> + <%= f.submit _('Save'), name: "draft", class: "btn btn-primary" %> + <%= link_to _('Cancel'), :back, class: "btn cancel btn-secondary" %>
    -
    - <%end%> + <% end %>
    -
    +
    diff --git a/app/views/guidance_groups/admin_show.html.erb b/app/views/guidance_groups/admin_show.html.erb index a5998ec..d73054d 100644 --- a/app/views/guidance_groups/admin_show.html.erb +++ b/app/views/guidance_groups/admin_show.html.erb @@ -1,13 +1,13 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t("org_admin.guidance.guidance_group_label") %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => "btn btn-primary" %> + class: "btn btn-primary" %>

    @@ -19,74 +19,44 @@ - + - + - - - - - + - - + + - - + +
    <%= t("org_admin.guidance_group.name_label") %><%= _('Name') %> <%= raw @guidance_group.name %>
    - <% if @guidance_group.dmptemplates.count == 1 then %> - <%= t("org_admin.guidance.template") %> - <% else %> - <%= t("org_admin.guidance.templates") %> - <% end %> - <%= _('Published') %> - <% i = 1 %> - <% if @guidance_group.dmptemplates.count == 0 then %> - <% list = Dmptemplate.funders_and_own_templates(current_user.organisation_id) %> - <% list.each do |tem| %> - <%= tem.title %> - <% if list.count > i then %> - , - <% i +=1 %> - <% end %> - <% end %> + <% if @guidance_group.published.nil? || !@guidance_group.published then %> + <%= _('No') %> <% else %> - <% @guidance_group.dmptemplates.each do |tem| %> - <%= tem.title %> - <% if @guidance_group.dmptemplates.count > i then %> - , - <% i +=1 %> - <% end %> - <% end %> - <% end %> -
    <%= t('org_admin.templates.published_label') %> - <% if @guidance_group.published.nil? || @guidance_group.published == false then %> - <%= t("helpers.no_label") %> - <% else %> - <%= t("helpers.yes_label") %> + <%= _('Yes') %> <% end %>
    <%= t("org_admin.guidance_group.subset") %><%= _('Optional subset') %> - <% if @guidance_group.optional_subset.nil? || @guidance_group.optional_subset == false then %> - <%= t('helpers.no_label') %> + <% if @guidance_group.optional_subset.nil? || !@guidance_group.optional_subset then %> + <%= _('No') %> <% else %> - <%= t('helpers.yes_label') %> + <%= _('Yes') %> <% end %>
    <%= t("org_admin.guidance.created") %><%= l @guidance_group.created_at.to_date, :formats => :short %><%= _('Created') %><%= l @guidance_group.created_at.to_date, formats: :short %>
    <%= t("org_admin.guidance.last_updated") %><%= l @guidance_group.updated_at.to_date, :formats => :short %><%= _('Last updated') %><%= l @guidance_group.updated_at.to_date, formats: :short %>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_group_path(@guidance_group.id), :class => "btn btn-primary" %> - <%= link_to t("helpers.submit.back"), :back, :class => "btn cancel" %> + <%= link_to _('Edit'), admin_edit_guidance_group_path(@guidance_group.id), class: "btn btn-primary" %> + <%= link_to _('Back'), :back, class: "btn cancel" %>

    - \ No newline at end of file + \ No newline at end of file diff --git a/app/views/guidances/_add_guidance.html.erb b/app/views/guidances/_add_guidance.html.erb new file mode 100644 index 0000000..bd036d2 --- /dev/null +++ b/app/views/guidances/_add_guidance.html.erb @@ -0,0 +1,83 @@ + +
    + <%= form_for :guidance, url: {action: "admin_create"}, html: {id: "new_guidance_form"} do |f| %> + + + + + + + + + + + + + + + + + +
    <%= _('Text') %> +
    + <%= text_area_tag("guidance-text", "", class: "tinymce") %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "guidance_text_popover", rel: "popover", "data-html" => "true", "data-content" => _('Enter your guidance here. You can include links where needed.'))%> +
    +
    +
    <%= _('Should this guidance apply:') %> + +
    <%= _('Published') %> +
    + <%= f.check_box :published , as: :check_boxes %> +
    +
    <%= _('Guidance group') %> +
    + <%= f.collection_select(:guidance_group_ids, + GuidanceGroup.where(org_id: current_user.org_id).order("name ASC"), + :id, :name, {prompt: false, include_blank: _('None')}, {multiple: false})%> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "guidance_group_select_popover", rel: "popover", "data-html" => "true", "data-content" => _('Select which group this guidance relates to.'))%> +
    +
    +
    + + + +
    + <%= _('Save')%> + + <%= link_to _('Cancel'), :back, class: "btn cancel" %> +
    + +
    + <%= tinymce :content_css => asset_path('application.css') %> + <% end %> +
    + + + + + \ No newline at end of file diff --git a/app/views/guidances/_edit_guidance.html.erb b/app/views/guidances/_edit_guidance.html.erb new file mode 100644 index 0000000..ffae58d --- /dev/null +++ b/app/views/guidances/_edit_guidance.html.erb @@ -0,0 +1,26 @@ + +<%= form_for(suggested_answer, url: admin_update_suggested_answer_path(suggested_answer), html: { method: :put}) do |f| %> + <%= f.hidden_field :org_id, value: current_user.org_id %> + + + + + + +
    <%= _('Suggested answer/ Example')%> +
      +
    • <%= f.select :is_example, {_('Example Answer') => true, _('Suggested answer') => false} %>
    • +
    • <%= f.text_area :text, rows: 5 %>
    • +
    +
    +
    + + +
    + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Delete'), admin_destroy_suggested_answer_path(id: suggested_answer.id), + confirm: _("You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-primary"%> + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Cancel'), "#", class: "btn cancel cancel_edit_suggested_answer" %> +
    +<%end%> diff --git a/app/views/guidances/_guidance_display.html.erb b/app/views/guidances/_guidance_display.html.erb new file mode 100644 index 0000000..b3bce3b --- /dev/null +++ b/app/views/guidances/_guidance_display.html.erb @@ -0,0 +1,36 @@ + + +
    +
    + <% if !question.get_guidance_annotation(current_user.org).nil? && question.get_guidance_annotation(current_user.org) != "" %> +
    + +
    +
    <%= raw question.get_guidance_annotation(current_user.org).text %>
    +
    +
    + <% end %> + + <% question.guidance_for_org(current_user.org).each_pair do |title,guidance| %> +
    + +
    +
    <%= raw guidance.text %>
    +
    +
    + <% end %> +
    + +
    diff --git a/app/views/guidances/admin_edit.html.erb b/app/views/guidances/admin_edit.html.erb index e6a47f9..b8ddce7 100644 --- a/app/views/guidances/admin_edit.html.erb +++ b/app/views/guidances/admin_edit.html.erb @@ -2,16 +2,16 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance_label') %> + <%= _('Guidance') %>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path, - :class => 'btn btn-primary' %> - <%= link_to t("org_admin.guidance.view_all_guidance"), + class: 'btn btn-primary' %> + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => 'btn btn-primary' %> -
    + class: 'btn btn-primary' %> +

    @@ -19,139 +19,84 @@
    - <%= form_for(@guidance, :url => admin_update_guidance_path(@guidance), :html => { :method => :put , :id => 'edit_guidance_form'}) do |f| %> - + <%= form_for(@guidance, url: admin_update_guidance_path(@guidance), html: { method: :put , id: 'edit_guidance_form'}) do |f| %> + - - + - - + - + - - - - + + + + - - + - +
    <%= t('org_admin.guidance.text_label') %>
    +
    <%= _('Text') %> +
    <%= text_area_tag("guidance-text", @guidance.text, class: "tinymce") %>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_text_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.text_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Enter your guidance here. You can include links where needed.'))%>
    <%= t('org_admin.guidance.by_theme_or_by_question') %>
    - <% if !@guidance.question_id.nil? then %> - <% select_op = 2 %> - <% else%> - <% select_op = 1%> - <%end%> - <%= hidden_field 'select_op' , :value => select_op, :id => 'edit_guid_ques_flag' %> - - <%= select_tag "g_options", options_for_select({t('org_admin.guidance.by_themes_label') => 1, - t('org_admin.guidance.by_question_label') => 2}, select_op) %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_apply_to_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.apply_to_help_text_html'))%> -
    -
    - - -
    <%= _('Themes') %> +
    - <%= f.collection_select(:theme_ids, - Theme.all.order('title'), - :id, :title, {:prompt => false, :include_blank => 'None'}, {:multiple => true})%> + <%= f.collection_select(:theme_ids, @themes, :id, :title, + {prompt: false, include_blank: 'None'}, {multiple: true})%>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_by_themes_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.by_themes_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which theme(s) this guidance relates to.'))%>
    - -
    - +
    <%= t('org_admin.guidance.published') %>
    - <%= f.check_box :published , :as => :check_boxes%> -
    -
    - -
    -
    <%= _('Published') %>
    + <%= f.check_box :published , as: :check_boxes%> +
    +
    <%= t('org_admin.guidance.guidance_group_label') %>
    - <%= f.collection_select(:guidance_group_ids, - GuidanceGroup.where("organisation_id = ?", current_user.organisation_id).order('name ASC'), - :id, :name, {:prompt => false, :include_blank => 'None'}, {:multiple => false})%> +
    <%= _('Guidance group') %> +
    + <%= f.collection_select(:guidance_group_id, @guidance_groups, + :id, :name, {prompt: false, include_blank: 'None'}, {multiple: false})%>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_group_select_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_select_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which group this guidance relates to.'))%>
    - +
    - + - +
    - <%= t('helpers.submit.save')%> - <%= link_to t('helpers.submit.cancel'), :back, :class => 'btn cancel' %> + <%= _('Save')%> + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>
    - +
    <%= tinymce :content_css => asset_path('application.css') %> <%end%>
    -
    + diff --git a/app/views/guidances/admin_index.html.erb b/app/views/guidances/admin_index.html.erb index 76acaf2..6010b35 100644 --- a/app/views/guidances/admin_index.html.erb +++ b/app/views/guidances/admin_index.html.erb @@ -3,172 +3,138 @@

    - <%= t("org_admin.guidance_group.guidance_group_list") %> + <%= _('Guidance group list') %>

    - <%= raw t("org_admin.guidance_group.guidance_group_text_html")%> + <%= raw _("

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    ")%>
    - <%= link_to t("org_admin.guidance_group.add_guidance_group"), admin_new_guidance_group_path(), :class => "btn btn-primary" %> + <%= link_to _('Add guidance group'), admin_new_guidance_group_path(), class: "btn btn-primary" %>
    - + -<% if @guidance_groups.count > 0 then%> +<% if @guidance_groups.length > 0 then%> - - - - - - + + + + + <% !@guidance_groups.each do |guidance_gr| %> - - <% guidance_group_temp = guidance_gr.dmptemplate_ids %> - <% if guidance_group_temp != [] then %> - - <%else%> - - <%end%> - - - - - - - - <%end%> + + + + + + + + <% end %>
    <%= t("org_admin.guidance_group.name_label") %><%= t("org_admin.guidance.template") %><%= t("org_admin.guidance.published") %><%= t("org_admin.guidance_group.subset") %><%= t("org_admin.guidance.last_updated") %><%= t("org_admin.guidance.actions") %><%= _('Name') %><%= _('Published') %><%= _('Optional subset') %><%= _('Last updated') %><%= _('Actions') %>
    - <%= guidance_gr.name %> - - <% i = 1 %> - <% guidance_group_temp.each do |t| %> - <% temp = Dmptemplate.find(t) %> - <%= temp.title %> - - <% if guidance_group_temp.count > i then%> - , - <% i +=1 %> - <% end %> - <%end%> - - <%= t("org_admin.guidance_group.all_temp")%> - - <%if guidance_gr.published.nil? || guidance_gr.published == false then%> - <%= t("helpers.no_label")%> - <%else%> - <%= t("helpers.yes_label")%> - <%end%> - - <%if guidance_gr.optional_subset.nil? || guidance_gr.optional_subset == false then%> - <%= t("helpers.no_label")%> - <%else%> - <%= t("helpers.yes_label")%> - <%end%> - - <%= l guidance_gr.updated_at.to_date, :formats => :short %> - - <%= link_to t("helpers.view"), admin_show_guidance_group_path(guidance_gr), :class => "dmp_table_link"%>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_group_path(guidance_gr), :class => "dmp_table_link"%>
    - <%= link_to t("helpers.submit.delete"), admin_destroy_guidance_group_path(guidance_gr), - :data => {:confirm => t("org_admin.guidance_group.delete_message", :guidance_group_name => guidance_gr.name )}, :method => :delete, :class => "dmp_table_link"%> -
    + <%= guidance_gr.name %> + + <% if guidance_gr.published.nil? || guidance_gr.published == false then%> + <%= _('No')%> + <% else %> + <%= _('Yes')%> + <% end %> + + <% if guidance_gr.optional_subset.nil? || guidance_gr.optional_subset == false then%> + <%= _('No')%> + <% else %> + <%= _('Yes')%> + <% end %> + + <%= l guidance_gr.updated_at.to_date, formats: :short %> + + <%= link_to _('View'), admin_show_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    + <%= link_to _('Edit'), admin_edit_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    + <%= link_to _('Delete'), admin_destroy_guidance_group_path(guidance_gr), data: {confirm: _("You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?") % { :guidance_group_name => guidance_gr.name }}, method: :delete, class: "dmp_table_link"%> +
    -<%end%> +<%end%>

    - <%= t("org_admin.guidance.guidance_list") %> + <%= _('Guidance list') %>

    - <%= raw t("org_admin.guidance.guidance_text_html")%> + <%= raw _('

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    ')%>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path(), - :class => "btn btn-primary" %> + class: "btn btn-primary" %>
    -<% if @guidances.count > 0 then%> +<% if @guidances.length > 0 then%> - - - - - - + + + + + <% @guidances.each do |guidance| %> - <% if guidance.in_group_belonging_to?(current_user.organisation_id) then %> + <% if guidance.in_group_belonging_to?(current_user.org_id) then %> - <% if guidance.themes != [] then %> + <% if guidance.themes.present? then %> - <%else%> + <% else %> - <%end%> - <% if !guidance.question_id.nil? then %> - - <%else%> + <% end %> + <% if guidance.guidance_group.present? then %> + + <% else %> - <%end%> - <% if guidance.guidance_groups != [] then %> - - <%else%> - - <%end%> + - + + <% end %> - <%end%> - <%end%> + <% end %> + <% end %>
    <%= t("org_admin.guidance.text_label") %><%= t("org_admin.guidance.themes_label") %><%= t("org_admin.guidance.question_label") %><%= t("org_admin.guidance.guidance_group_label") %><%= t("org_admin.guidance.last_updated") %><%= t("org_admin.guidance.actions") %><%= _('Text') %><%= _('Themes') %><%= _('Guidance group') %><%= _('Last updated') %><%= _('Actions') %>
    <%= guidance.text.html_safe%> <% guidance.themes.each do |th| %> <%= th.title %> - <%end%> + <% end %> - - <%= raw guidance.question.text.truncate(70, omission: t('helpers.truncate_continued')) %> - + <%= guidance.guidance_group.name %> + - - - - <% guidance.guidance_groups.each do |p|%> - <%= p.name %> - <%end%> - - - - - <%= l guidance.updated_at.to_date, :formats => :short %> + <%= l guidance.updated_at.to_date, formats: :short %> - <%= link_to t("helpers.view"), admin_show_guidance_path(guidance), :class => "dmp_table_link"%>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_path(guidance), :class => "dmp_table_link"%>
    - <%= link_to t("helpers.submit.delete"), admin_destroy_guidance_path(guidance), - :data => {:confirm => t("org_admin.guidance.delete_message_html", :guidance_summary => truncate(sanitize(guidance.text,:tags => %w(br a)), :length => 20 , :omission => t('helpers.truncate_continued')) )}, :method => :delete, :class => "dmp_table_link"%> + <%= link_to _('View'), admin_show_guidance_path(guidance), class: "dmp_table_link"%>
    + <%= link_to _('Edit'), admin_edit_guidance_path(guidance), class: "dmp_table_link"%>
    + <%= link_to _('Delete'), admin_destroy_guidance_path(guidance), + data: {confirm: _("You are about to delete '%{guidance_summary}'. Are you sure?") % { :guidance_summary => truncate(sanitize(guidance.text,tags: %w(br a)), length: 20 , omission: _('... (continued)'))} }, method: :delete, class: "dmp_table_link"%>
    -<%end%> +<% end %> diff --git a/app/views/guidances/admin_new.html.erb b/app/views/guidances/admin_new.html.erb index bf37fe1..59b5397 100644 --- a/app/views/guidances/admin_new.html.erb +++ b/app/views/guidances/admin_new.html.erb @@ -2,126 +2,98 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance.new_label') %> + <%= _('New guidance') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => 'btn btn-primary' %> -
    + class: 'btn btn-primary' %> +

    - <%= form_for :guidance, :url => {:action => 'admin_create'}, :html => {:id => 'new_guidance_form'} do |f| %> + <%= form_for :guidance, url: {action: 'admin_create'}, html: {id: 'new_guidance_form'} do |f| %> - - + - - + - + - + - +
    <%= t('org_admin.guidance.text_label') %>
    +
    <%= _('Text') %> +
    <%= text_area_tag("guidance-text", "", class: "tinymce") %>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_text_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.text_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Enter your guidance here. You can include links where needed.'))%>
    <%= t('org_admin.guidance.by_theme_or_by_question') %>
    - <%= select_tag "g_options", options_for_select([[t('org_admin.guidance.by_themes_label'), 1], - [t('org_admin.guidance.by_question_label'), 2]]) %> -
    -
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_apply_to_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.apply_to_help_text_html'))%> -
    -
    - -
    <%= _('Themes') %> +
    - <%= f.collection_select(:theme_ids, - Theme.all.order('title'), - :id, :title, {:prompt => false, :include_blank => 'None'}, {:multiple => true})%> + <%= f.collection_select(:theme_ids, @themes, + :id, :title, {prompt: false, include_blank: 'None'}, {multiple: true})%>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_by_themes_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.by_themes_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which theme(s) this guidance relates to.'))%>
    - -
    - + +
    <%= t('org_admin.guidance.published') %><%= _('Published') %>
    - <%= f.check_box :published , :as => :check_boxes%> + <%= f.check_box :published , as: :check_boxes%>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_group_subset_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_published_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Check this box when you are ready for this guidance to appear on user's plans."))%>
    <%= t('org_admin.guidance.guidance_group_label') %><%= _('Guidance group') %>
    - <%= f.collection_select(:guidance_group_ids, - GuidanceGroup.where("organisation_id = ?", current_user.organisation_id).order('name ASC'), - :id, :name, {:prompt => false, :include_blank => 'None'}, {:multiple => false})%> + <%= f.collection_select(:guidance_group_id, @guidance_groups, + :id, :name, {prompt: false, include_blank: 'None'}, {multiple: false})%>
    - <%= link_to( image_tag('help_button.png'), '#', :class => 'guidance_group_select_popover', :rel => "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_select_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which group this guidance relates to.'))%>
    - +
    - + - +
    - <%= t("helpers.submit.save")%> - - <%= link_to t('helpers.submit.cancel'), :back, :class => 'btn cancel' %> + <%= _('Save')%> + + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>
    - +
    <%= tinymce :content_css => asset_path('application.css') %> <%end%>
    -
    + \ No newline at end of file diff --git a/app/views/guidances/admin_show.html.erb b/app/views/guidances/admin_show.html.erb index a8f8d6e..4742641 100644 --- a/app/views/guidances/admin_show.html.erb +++ b/app/views/guidances/admin_show.html.erb @@ -1,17 +1,17 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t("org_admin.guidance_label") %> + <%= _('Guidance') %>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path, - :class => "btn btn-primary" %> - <%= link_to t("org_admin.guidance.view_all_guidance"), + class: "btn btn-primary" %> + <%= link_to _('View all guidance'), admin_index_guidance_path, - :class => "btn btn-primary" %> -
    + class: "btn btn-primary" %> +

    @@ -19,57 +19,45 @@
    - + - + - <% if @guidance.themes !=[] then %> - - - - - <%end%> - <% if !@guidance.question_id.nil? %> - - - - - <%end%> - - + + + + + - + - - + + - - + + - +
    <%= t("org_admin.guidance.text_label") %><%= _('Text') %> <%= raw @guidance.text %>
    <%= t("org_admin.guidance.themes_label") %><% @guidance.themes.each do |th|%> - <%= th.title %> - <%end%> -
    <%= t("org_admin.guidance.question_label") %><%= raw @guidance.question.text %>
    <%= t("org_admin.guidance.guidance_group_label") %><% @guidance.guidance_groups.each do |p|%> - <%= p.name %> - <%end%> + <%= _('Themes') %><%= @guidance.themes.order(:title).collect{|t| t.title}.join(', ') %>
    <%= _('Guidance group') %> + <%= @guidance.guidance_group.name %>
    <%= t("org_admin.guidance.published") %><%= _('Published') %> <%if @guidance.published == false || @guidance.published.nil? then%> - <%= t("helpers.no_label")%> - <%else%> - <%= t("helpers.yes_label")%> - <%end%> + <%= _('No')%> + <% else %> + <%= _('Yes')%> + <% end %>
    <%= t("org_admin.guidance.created") %><%= l @guidance.created_at.to_date, :formats => :short %><%= _('Created') %><%= l @guidance.created_at.to_date, formats: :short %>
    <%= t("org_admin.guidance.last_updated") %><%= l @guidance.updated_at.to_date, :formats => :short %><%= _('Last updated') %><%= l @guidance.updated_at.to_date, formats: :short %>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_path(@guidance.id), :class => "btn btn-primary"%> - <%= link_to t("helpers.submit.back"), :back, :class => "btn cancel" %> + <%= link_to _('Edit'), admin_edit_guidance_path(@guidance.id), class: "btn btn-primary"%> + <%= link_to _('Back'), :back, class: "btn cancel" %>

    -
    \ No newline at end of file + \ No newline at end of file diff --git a/app/views/guidances/update_phases.js.erb b/app/views/guidances/update_phases.js.erb deleted file mode 100644 index 3be4344..0000000 --- a/app/views/guidances/update_phases.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -$('#phases_select').html("<%= escape_javascript(options_for_select(@phases)) %>"); -$('#versions_select').html("<%= escape_javascript(options_for_select(@versions)) %>"); -$('#sections_select').html("<%= escape_javascript(options_for_select(@sections)) %>"); -$('#questions_select').html("<%= escape_javascript(options_for_select(@questions)) %>"); - \ No newline at end of file diff --git a/app/views/guidances/update_questions.js.erb b/app/views/guidances/update_questions.js.erb deleted file mode 100644 index 56f5ceb..0000000 --- a/app/views/guidances/update_questions.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('#questions_select').html("<%= escape_javascript(options_for_select(@questions)) %>hiya"); \ No newline at end of file diff --git a/app/views/guidances/update_sections.js.erb b/app/views/guidances/update_sections.js.erb deleted file mode 100644 index 710716c..0000000 --- a/app/views/guidances/update_sections.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('#sections_select').html("<%= escape_javascript(options_for_select(@sections)) %>"); -$('#questions_select').html("<%= escape_javascript(options_for_select(@questions)) %>"); \ No newline at end of file diff --git a/app/views/guidances/update_versions.js.erb b/app/views/guidances/update_versions.js.erb deleted file mode 100644 index f8bcf54..0000000 --- a/app/views/guidances/update_versions.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -$('#versions_select').html("<%= escape_javascript(options_for_select(@versions)) %>"); -$('#sections_select').html("<%= escape_javascript(options_for_select(@sections)) %>"); -$('#questions_select').html("<%= escape_javascript(options_for_select(@questions)) %>"); \ No newline at end of file diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index 4c03d50..92bfeb2 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -2,13 +2,10 @@
    -

    <%= raw t('welcome_title')%>

    - <%= raw t('welcome_text', - application_name: Rails.configuration.branding[:application][:name], - organisation_name: Rails.configuration.branding[:organisation][:name])%> - +

    <%= _('Welcome.')%>

    + <%= raw _('

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    ') % {:application_name => Rails.configuration.branding[:application][:name], :organisation_name => Rails.configuration.branding[:organisation][:name]} %>
    -

    <%= t('screencast_text', application_name: Rails.configuration.branding[:application][:name]) %>

    +

    <%= _('Screencast on how to use %{application_name}') % {:application_name => Rails.configuration.branding[:application][:name]} %>

    @@ -30,7 +27,7 @@
    - <%= t('helpers.sign_in')%> + <%= _('Sign in')%>
    @@ -41,9 +38,9 @@
    - <%= t('helpers.sign_up') %> + <%= _('Create account') %>

    - <%= t('helpers.sign_up_text', application_name: Rails.configuration.branding[:application][:name])%> + <%= _('New to %{application_name}? Create an account today.') % {:application_name => Rails.configuration.branding[:application][:name]} %>

    diff --git a/app/views/layouts/_branding.html.erb b/app/views/layouts/_branding.html.erb index 7c436ff..4774bee 100644 --- a/app/views/layouts/_branding.html.erb +++ b/app/views/layouts/_branding.html.erb @@ -1,19 +1,19 @@
    <% if user_signed_in? %> - <% if !current_user.organisation.nil? %> + <% if !current_user.org.nil? %> - <% if current_user.organisation.logo.present? %> + <% if current_user.org.logo.present? %> <% end %> - <% if current_user.organisation.banner_text.present? %> + <% if current_user.org.banner_text.present? %>
    - <%= raw current_user.organisation.banner_text %> + <%= raw current_user.org.banner_text %>
    <%end%> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index f8728e7..4866e06 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -3,9 +3,9 @@ @@ -24,7 +24,7 @@
  • + <% end %> + + + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index c598adc..483511b 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,7 +1,7 @@ - + - <%= t('tool_title', application_name: Rails.configuration.branding[:application][:name])%> + <%= _('%{application_name}') % { :application_name => Rails.configuration.branding[:application][:name] } %> <%= favicon_link_tag "favicon.ico" %> <%= render "layouts/header" %> + +
    <% if notice %> -

    <%= notice %>

    +

    <%= raw notice %>

    <% end %> <% if alert %> -

    <%= alert %>

    +

    <%= raw alert %>

    <% end %>
    diff --git a/app/views/notes/_add.html.erb b/app/views/notes/_add.html.erb new file mode 100644 index 0000000..2817b90 --- /dev/null +++ b/app/views/notes/_add.html.erb @@ -0,0 +1,24 @@ + + +<% + new_note = Note.new + questionid = question.id +%> + +<%= form_for( :new_note, + url: notes_path, + remote: true, + html: {method: :post, class: "add_note_form roadmap-form"}, + id: "new_note_form_#{questionid}") do |f| %> + <%= f.hidden_field :user_id, value: current_user.id %> + <%= f.hidden_field :question_id, value: questionid %> + <%= f.hidden_field :answer_id, value: answer.id %> + <%= f.hidden_field :plan_id, value: plan_id %> + +
    + <%= label_tag "#{questionid}new_note_text", _('Share note with collaborators') %> + <%= text_area_tag "#{questionid}new_note_text", nil, class: "tinymce" %> + <%= tinymce :content_css => asset_path('application.css') %> + +
    +<% end %> diff --git a/app/views/notes/_archive.html.erb b/app/views/notes/_archive.html.erb new file mode 100644 index 0000000..eae2154 --- /dev/null +++ b/app/views/notes/_archive.html.erb @@ -0,0 +1,20 @@ +<%= form_for(note, + url: archive_note_path(note), + remote: true, + class: "archive_note_form", + id: "archive_note_form_#{note.id}") do |f| %> + + <%= f.hidden_field :id, :value => note.id %> + <%= f.hidden_field :archived_by, :value => current_user.id %> + + <%= render :partial => "/notes/view", locals: {note: note} %> + +

    <%= _('Are you sure you want to remove this note?')%>

    + + +
    + <%= f.submit _('Remove'), onclick: "archive_note(#{note.id}, #{question_id})", :class => "btn btn-primary archive_comment_submit_button" %> + <%= link_to _('Cancel'), "#", onclick: "cancel_archive_note(#{note.id})", :class => "cancel_archive_comment btn cancel" %> +
    +
    +<% end %> diff --git a/app/views/notes/_edit.html.erb b/app/views/notes/_edit.html.erb new file mode 100644 index 0000000..17a75bc --- /dev/null +++ b/app/views/notes/_edit.html.erb @@ -0,0 +1,15 @@ + + +<%= form_for(note, + url: note_path(note), + remote: true, + html: {method: :put, class: "edit_note_form roadmap-form"}, + id: "edit_note_form_#{note.id}") do |f| %> + +
    + <%= f.hidden_field :id, :value => note.id %> + + <%= text_area_tag("#{note.id}_note_text".to_sym, note.text , class: "tinymce") %> + <%= f.submit _('Save'), :class => "form-submit edit_note_submit_button" %> +
    +<%end%> diff --git a/app/views/notes/_list.html.erb b/app/views/notes/_list.html.erb new file mode 100644 index 0000000..daf6a20 --- /dev/null +++ b/app/views/notes/_list.html.erb @@ -0,0 +1,85 @@ + + +<% if notes.count > 1 then%> + <% style_to_add = "height:150px; overflow-y:auto;" %> +<%else%> + <% style_to_add = "" %> +<%end%> + +
    + +
    + + + <% notes.each do |note|%> + + + + + <%end%> + +
    + <% user = note.user.name %> + <%= user %>
    + (<%= l note.updated_at, format: :custom %>) +
    + + <% if note.archived %> + + <% if note.archived_by == current_user.id %> + <%= _('Note removed by you')%> + <% else %> + <% archived_by_user = User.find(note.archived_by) %> + <%= _('Note removed by')%> <%= archived_by_user.name %> + <%end%> + + <%else%> + + <%= link_to _('View'),"#question-form-#{question_id}", onclick: "view_note_button(#{note.id}, #{question_id})", :class => "dmp_table_link view_comment_button" %> + + <% if current_user.id == note.user_id %> + <%= link_to _('Edit'),"#question-form-#{question_id}", onclick: "edit_note(#{note.id}, #{question_id})", :class => "dmp_table_link edit_comment_button" %> + <%= link_to _('Remove'),"#question-form-#{question_id}", onclick: "archive_note(#{note.id}, #{question_id})", :class => "dmp_table_link archive_comment_button" %> + <% end%> + + <% if plan.administerable_by?(current_user.id) && current_user.id != note.user_id %> + <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> + <%= link_to _('Remove'),"#question-form-#{question_id}", onclick: "archive_note(#{note.id}, #{question_id})", :class => "dmp_table_link archive_comment_button" %> + <% end%> + <%end%> + +
    +
    + +
    + + +<% notes_not_archived = notes.select { |n| n.archived.nil? } %> +<% latest_note = notes_not_archived.sort { |x,y| y.updated_at <=> x.updated_at }.first %> +<% if !latest_note.nil? then%> +
    + <%= render :partial => "/notes/view", locals: {note: latest_note} %> +
    +
    +<%end%> + +<%notes.each do |note|%> + + + + + + + + + +<%end%> diff --git a/app/views/notes/_view.html.erb b/app/views/notes/_view.html.erb new file mode 100644 index 0000000..0610f0c --- /dev/null +++ b/app/views/notes/_view.html.erb @@ -0,0 +1,11 @@ + +<% user = User.find(note.user_id) %> +
    +
    +
    +
      +
    • <%= _('Noted by:')%>

    • +
    • <%= user.name%> (<%= l note.updated_at, format: :custom %>)
    • +
    • <%= raw note.text %>
    • +
    +
    diff --git a/app/views/notes/archive.js.erb b/app/views/notes/archive.js.erb new file mode 100644 index 0000000..f2687fa --- /dev/null +++ b/app/views/notes/archive.js.erb @@ -0,0 +1,29 @@ + +// remove all tinymce explicitly or re-init will not work later +tinymce.remove(".tinymce"); + +// render the list of notes and invisible view and edit sections +<% listlabel = "#comment-question-area-#{@question.id}" %> +$("<%=listlabel%>").html( + "<%= escape_javascript( render partial: '/phases/note', locals: {question: @question, answer: @answer, plan: @plan } ) %>" +); + +// TODO: this duplicates what is in the .yml file +// DRY it out! +tinymce.init({ + selector: ".tinymce", + statusbar: false, + menubar: false, + toolbar: "bold italic | bullist numlist | link | table", + plugins: [ "table", "link", "paste" ], + target_list: false, + autoresize_min_height: 130, + extended_valid_elements: [ "a[href|target=_blank]" ], + paste_auto_cleanup_on_paste : true, + paste_remove_styles: true, + paste_retain_style_properties: "none", + paste_convert_middot_lists: true, + paste_remove_styles_if_webkit: true, + paste_remove_spans: true, + paste_strip_class_attributes: "all" +}); diff --git a/app/views/notes/create.js.erb b/app/views/notes/create.js.erb new file mode 100644 index 0000000..4cd1b85 --- /dev/null +++ b/app/views/notes/create.js.erb @@ -0,0 +1,31 @@ + +// rewrite the number of notes heading e.g. Notes(3) +<% noteslabel = "#notes_number_#{@question.id}" %> +$("<%=noteslabel%>").html("Notes (<%= @num_notes %>)"); + +// need to remove the existing tinymce editor otherwise +tinymce.remove(".tinymce"); + +// render the list of notes and invisible view and edit sections +<% listlabel = "#comment-question-area-#{@question.id}" %> +$("<%=listlabel%>").html( + "<%= escape_javascript( render partial: '/phases/note', locals: {question: @question, answer: @answer, plan: @plan } ) %>" +); + +tinymce.init({ + selector: ".tinymce", + statusbar: false, + menubar: false, + toolbar: "bold italic | bullist numlist | link | table", + plugins: [ "table", "link", "paste" ], + target_list: false, + autoresize_min_height: 130, + extended_valid_elements: [ "a[href|target=_blank]" ], + paste_auto_cleanup_on_paste : true, + paste_remove_styles: true, + paste_retain_style_properties: "none", + paste_convert_middot_lists: true, + paste_remove_styles_if_webkit: true, + paste_remove_spans: true, + paste_strip_class_attributes: "all" +}); diff --git a/app/views/notes/update.js.erb b/app/views/notes/update.js.erb new file mode 100644 index 0000000..45c5eb5 --- /dev/null +++ b/app/views/notes/update.js.erb @@ -0,0 +1,27 @@ + +// need to remove the existing tinymce editor otherwise +tinymce.remove(".tinymce"); + +// render the list of notes and invisible view and edit sections +<% listlabel = "#comment-question-area-#{@question.id}" %> +$("<%=listlabel%>").html( + "<%= escape_javascript( render partial: '/phases/note', locals: {question: @question, answer: @answer, plan: @plan } ) %>" +); + +tinymce.init({ + selector: ".tinymce", + statusbar: false, + menubar: false, + toolbar: "bold italic | bullist numlist | link | table", + plugins: [ "table", "link", "paste" ], + target_list: false, + autoresize_min_height: 130, + extended_valid_elements: [ "a[href|target=_blank]" ], + paste_auto_cleanup_on_paste : true, + paste_remove_styles: true, + paste_retain_style_properties: "none", + paste_convert_middot_lists: true, + paste_remove_styles_if_webkit: true, + paste_remove_spans: true, + paste_strip_class_attributes: "all" +}); diff --git a/app/views/organisation_users/admin_index.html.erb b/app/views/organisation_users/admin_index.html.erb deleted file mode 100644 index 933defc..0000000 --- a/app/views/organisation_users/admin_index.html.erb +++ /dev/null @@ -1,65 +0,0 @@ -<%= stylesheet_link_tag "admin" %> - -

    - <%= t('org_admin.users_list') %> -

    - -<%= raw t('org_admin.user_text_html')%> -<% @user_roles = current_user.organisation.user_org_roles %> - -<% @user_roles = @user_roles.uniq_by {|u| u.user_id } %> - - - - - - - - <% if current_user.organisation.token_permission_types.count > 0 %> - - <% end %> - - - <% form_tag admin_index_organisation_users_path, method: :put do %> - - <% @user_roles.each do |user_id| %> - <% if !user_id.user.nil? then%> - - - - - - <% if current_user.organisation.token_permission_types.count > 0 %> - - <% end %> - - <% end %> - <% end %> - - <%= submit_tag "Update API Privleges" %> - <% end %> -
    <%= t('org_admin.user_full_name') %><%= t('org_admin.user_name') %><%= t('org_admin.last_logged_in') %><%= t('org_admin.how_many_plans') %><%= t('org_admin.api_privleges') %>
    - <% if !user_id.user.name.nil? then%> - <%= user_id.user.name %> - <% end %> - - <%= user_id.user.email %> - - <% if !user_id.user.last_sign_in_at.nil? then%> - <%= l user_id.user.last_sign_in_at.to_date, :formats => :short %> - <% end %> - - <% if !user_id.user.project_groups.nil? then%> - <%= user_id.user.project_groups.count %> - <% end %> - - <%= check_box_tag "user_ids[]", user_id %> - -
    diff --git a/app/views/organisations/admin_edit.html.erb b/app/views/organisations/admin_edit.html.erb deleted file mode 100644 index 9a2548c..0000000 --- a/app/views/organisations/admin_edit.html.erb +++ /dev/null @@ -1,85 +0,0 @@ -<%= stylesheet_link_tag "admin" %> -<% javascript 'admin.js' %> - -

    - <%= t('org_admin.org_details_label') %> -

    - -
    - -
    - <%= form_for(@organisation, :url => admin_update_organisation_path(@organisation), :html => { :multipart => true, :id => "edit_org_details", :method => :put}) do |f| %> - - - - - - - - - - - - - - - <% if @organisation.logo.present? %> - - - - - - - - - <%end%> - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= t('org_admin.org_name') %><%= f.text_field :name, :as => :string, :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.name_help_text') %>
    <%= t('org_admin.org_abbr') %> -
    - <%= f.text_field :abbreviation, :as => :string, :class => 'text_field' %> -
    -
    -
    <%= t('org_admin.org_logo') %><%= image_tag @organisation.logo.url %>
    <%= f.check_box :remove_logo %>   <%= t('org_admin.remove_logo') %>
    <%= t('org_admin.new_org_logo') %><%= f.file_field :logo %>
    <%= t('org_admin.org_banner_text') %><%= text_area_tag("org_banner_text", @organisation.banner_text, class: "tinymce") %>
    <%= t('org_admin.org_target_url') %><%= f.text_field :target_url, :as => :string, :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.target_url_help_text') %>
    <%= t('org_admin.org_contact_email') %><%= f.text_field :contact_email, :as => :string, :class => 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => t('org_admin.org_contact_email_help_text') %>
    <%= t('org_admin.org_type') %> - <%= @organisation.organisation_type.name %> -
    - -
    - - -
    - <%= f.submit t('helpers.submit.save'), :class => 'btn btn-primary' %> - <%= link_to t('helpers.submit.cancel'), :back, :class => 'btn btn-primary' %> -
    - <% end %> - -
    -
    - -<%= tinymce :content_css => asset_path('application.css') %> - diff --git a/app/views/organisations/admin_show.html.erb b/app/views/organisations/admin_show.html.erb deleted file mode 100644 index f853368..0000000 --- a/app/views/organisations/admin_show.html.erb +++ /dev/null @@ -1,78 +0,0 @@ -<%= stylesheet_link_tag "admin" %> - -

    - <%= t('org_admin.org_details_label') %> -

    -<%= t('org_admin.org_text')%> -
    -
    - -
    - -
    - - - - <% if @organisation.name.present? then%> - - - - - <% if @organisation.logo.present? then%> - - <%end%> - - <%end%> - <% if @organisation.abbreviation.present? then%> - - - - - <%end%> - <% if @organisation.banner_text.present? then%> - - - - - <%end%> - <% if @organisation.target_url.present? then%> - - - - - <%end%> - <% if @organisation.contact_email.present? then%> - - - - - <%end%> - <% if @organisation.organisation_type_id.present? then%> - - - - - <%end%> - <% if @organisation.parent_id.present? then%> - - - - - <%end%> - - - - -
    <%= t('org_admin.org_name') %><%= @organisation.name %>
    <%= t('org_admin.org_abbr') %><%= @organisation.abbreviation %>
    <%= t('org_admin.org_banner_text') %><%= raw @organisation.banner_text %>
    <%= t('org_admin.org_target_url') %><%= @organisation.target_url %>
    <%= t('org_admin.org_contact_email') %><%= @organisation.contact_email %>
    <%= t('org_admin.org_type') %><%= @organisation.organisation_type.name %>
    <%= t('org_admin.parent_org') %><%= @organisation.parent.name %>
    <%= t('org_admin.last_updated') %><%= l @organisation.updated_at.to_date, :formats => :short %>
    - -
    -
    - -
    - <%= link_to t("helpers.submit.edit"), admin_edit_organisation_path(current_user.organisation), :class => 'btn btn-primary'%> -
    -
    -
    -
    \ No newline at end of file diff --git a/app/views/orgs/admin_edit.html.erb b/app/views/orgs/admin_edit.html.erb new file mode 100644 index 0000000..3bbc468 --- /dev/null +++ b/app/views/orgs/admin_edit.html.erb @@ -0,0 +1,83 @@ +<%= stylesheet_link_tag "admin" %> +<% javascript 'admin.js' %> + +

    + <%= _('Organisation details') %> +

    + +
    + +
    + <%= form_for(@org, url: admin_update_org_path(@org), html: { multipart: true, id: "edit_org_details", method: :put}) do |f| %> + + + + + + + + + + + + + + + <% if @org.logo.present? %> + + + + + + + + + <%end%> + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= _('Name') %><%= f.text_field :name, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _("Please enter your organisation's name.") %>
    <%= _('Abbreviation') %> +
    + <%= f.text_field :abbreviation, as: :string, class: 'text_field' %> +
    +
    +
    <%= _('Logo') %><%= image_tag @org.logo.url %>
    <%= f.check_box :remove_logo %>   <%= _('If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo.') %>
    <%= _('Upload a new logo file') %><%= f.file_field :logo %>
    <%= _('Top banner text') %><%= text_area_tag("org_banner_text", @org.banner_text, class: "tinymce") %>
    <%= _('Website') %><%= f.text_field :target_url, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _('Please enter a valid web address.') %>
    <%= _('Contact Email') %><%= f.text_field :contact_email, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _('The email address of an administrator at your organisation. Your users will use this address if they have questions.') %>
    <%= _('Organisation type') %><%= @org.type %>
    + +
    + + +
    + <%= f.submit _('Save'), class: 'btn btn-primary' %> + <%= link_to _('Cancel'), :back, class: 'btn btn-primary' %> +
    + <% end %> + +
    +
    + +<%= tinymce :content_css => asset_path('application.css') %> + diff --git a/app/views/orgs/admin_show.html.erb b/app/views/orgs/admin_show.html.erb new file mode 100644 index 0000000..a3da37b --- /dev/null +++ b/app/views/orgs/admin_show.html.erb @@ -0,0 +1,86 @@ +<%= stylesheet_link_tag "admin" %> + +

    + <%= _('Organisation details') %> +

    +<%= _('These are the basic details for your organisation.')%> +
    +
    +
    + +
    + + + + <% if @org.name.present? then %> + + + + + <% if @org.logo.present? then %> + + <% end %> + + <% end %> + + <% if @org.abbreviation.present? then %> + + + + + <% else %> + + + + <% end %> + + <% if @org.banner_text.present? then %> + + + + + <% end %> + + <% if @org.target_url.present? then %> + + + + + <% end %> + + <% if @org.contact_email.present? then %> + + + + + <% end %> + + <% if @org.org_type != 0 then %> + + + + + <% end %> + + <% if @org.parent_id.present? then %> + + + + + <% end %> + + + + + +
    <%= _('Name') %><%= @org.name %>
    <%= _('Abbreviation') %><%= @org.abbreviation %>
    <%= _('Abbreviation') %><%= _('Please add an abbreviation to your org for display with annotations!')%>
    <%= _('Top banner text') %><%= raw @org.banner_text %>
    <%= _('Website') %><%= @org.target_url %>
    <%= _('Contact Email') %><%= @org.contact_email %>
    <%= _('Organisation type') %><%= @org.type %>
    <%= _('Main organisation') %><%= @org.parent.name %>
    <%= _('Last updated') %><%= l @org.updated_at.to_date, formats: :short %>
    + +
    +
    + +
    + <%= link_to _('Edit'), admin_edit_org_path(current_user.org), class: 'btn btn-primary'%> +
    +
    +
    +
    \ No newline at end of file diff --git a/app/views/phases/_answer_form.html.erb b/app/views/phases/_answer_form.html.erb new file mode 100644 index 0000000..c95732b --- /dev/null +++ b/app/views/phases/_answer_form.html.erb @@ -0,0 +1,123 @@ + + +
    + <% + answers = question.plan_answers(plan.id) + if answers.present? + answer = answers.first + else + answer = Answer.new({ plan_id: plan.id, question_id: question.id, user_id: current_user.id }) + if question.default_value.present? + answer.text = question.default_value + end + end + %> +
    +
    " class="answer-locking">
    +
    "> + <%= render(partial: 'answers/new_edit', locals: { question: question, answer: answer, readonly: readonly }) %> +
    +
    " class="answer-status"> + <%= render(partial: 'answers/status', locals: { answer: answer }) %> +
    +
    +
    + + +
    + +
    + <% comments = answer.notes.all %> + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <% active_tab = nil %> +
      + <% annotations = question.annotations.where(type: Annotation.types[:guidance]) %> + <% if annotations.present? || question_guidances.present? %> + <% active_tab = 'guidance_tab' %> +
    • + <%= link_to _('Guidance'), "#", class: "right_column_tab_link" %> +
    • + <% else %> + <% active_tab = 'note_tab' %> + <% end %> +
    • "> + <% if comments.count > 0 %> + <%= link_to "#{_('Notes')} (#{comments.count})" , "#", id: "notes_number_#{question.id}", class: "right_column_tab_link" %> + <% else %> + <%= link_to _('Share note'), "#", id: "notes_number_#{question.id}", class: "right_column_tab_link" %> + <% end %> +
    • +
    +
    + + + +
    +
    + + + <% num_annotations = 0 %> + <% if annotations.present? %> + <% annotations.each do |annotation| %> + +
    + + + + + +
    +
    <%= raw annotation.text %>
    +
    + <% num_annotations += 1%> +
    + <% end %> + <% end %> + + + <% guidance_accordion_id = num_annotations %> + <% question_guidances.each_pair do |theme, group| %> + <% group.each do |gobj| %> +
    + +
    +
    <%= raw gobj[:text] %>
    +
    + <% guidance_accordion_id += 1 %> +
    + <% end %> + <% end %> + +
    +
    + +
    + <%= render partial: "note", locals: {question: question, answer: answer, plan: plan, suffix: "" }%> +
    +
    + + +<% if last_question_id == question.id then %> +
    +<% else %> +
    +<% end %> diff --git a/app/views/phases/_edit_phase.html.erb b/app/views/phases/_edit_phase.html.erb new file mode 100644 index 0000000..de7b425 --- /dev/null +++ b/app/views/phases/_edit_phase.html.erb @@ -0,0 +1,46 @@ + + +<%= form_for(phase, url: admin_update_phase_path(phase.id), html: { method: :put}) do |f| %> + +

    + <%= _('Phase details')%> +

    +
    + <%= raw _("

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    ")%> +

    +
    +
    + + + + + + + + + + + + + + +
    <%= _('Title') %><%= f.text_field :title, + as: :string, + class: 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP') %>
    <%= _('Order of display') %><%= f.number_field :number, in: 0..5, class: "number_field has-tooltip", 'data-toggle' => "tooltip", 'title' => _('This allows you to order the phases of your template.') %>
    <%= _('Description') %> +
    + <%= text_area_tag("phase-desc", phase.description, class: "tinymce") %> +
    +
    + <%= link_to( image_tag('help_button.png'), '#', class: 'phase_desc_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer."))%> +
    +
    +
    +
    + + +
    + <%= f.submit _('Save'), class: 'btn btn-primary' %> + <%= link_to _('Cancel'), admin_show_phase_path(phase), class: 'btn cancel' %> +
    + +<% end %> \ No newline at end of file diff --git a/app/views/phases/_note.html.erb b/app/views/phases/_note.html.erb new file mode 100644 index 0000000..c296d9b --- /dev/null +++ b/app/views/phases/_note.html.erb @@ -0,0 +1,29 @@ + <% if answer.present? && answer.notes.any? %> + <% notes = answer.notes.all.to_a.sort! {|x,y| y.updated_at <=> x.updated_at } %> + <% questionid = question.id %> + <%= hidden_field_tag :question_id, questionid, class: "question_id" %> + + +
    + <%= link_to _('Add note'), + "#question-form-#{questionid}", + class: "btn btn-primary add_comment_button", + onclick: "add_note_button(#{questionid})" + %> +
    + +
    + + + <%= render :partial => "/notes/list", locals: {question_id: question.id, notes: notes, plan: plan} %> + + +
    + + + + <% else%> + <%= render :partial => "/notes/add", locals: {answer: answer, question: question, plan_id: plan.id }%> + <% end%> diff --git a/app/views/phases/_show_phase.html b/app/views/phases/_show_phase.html new file mode 100644 index 0000000..ecb5dd4 --- /dev/null +++ b/app/views/phases/_show_phase.html @@ -0,0 +1,37 @@ + + +

    + <%= _('Phase details')%> + + + <% if @phase.modifiable && @edit %> +
    + <%= link_to _('Edit phase details'), '#', class: "btn btn-primary", id: "edit_phase_button"%> +
    + <% end %> +

    + +<% if @phase.template.org.not_funder %> +
    + <%= raw _('

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    ')%> +

    +<% end %> + +
    +
    + + + + + + + + + + + + + + +
    <%= _('Title') %><%= @phase.title %>
    <%= _('Order of display') %><%= @phase.number %>
    <%= _('Description') %><%= raw @phase.description %>
    +
    diff --git a/app/views/phases/admin_add.html.erb b/app/views/phases/admin_add.html.erb new file mode 100644 index 0000000..546c727 --- /dev/null +++ b/app/views/phases/admin_add.html.erb @@ -0,0 +1,74 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> +<% javascript "admin.js" %> + +

    + <%= @template.title %> + +
    + <%= link_to _('View all templates'), + admin_index_template_path, + class: "btn btn-primary" %> +
    +

    + +
    + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @template, active: "add_plan"} %> + + +
    +
    + + +
    +
    + + + <%= form_for :phase, {url: admin_create_phase_path} do |f| %> +

    + <%= _('Phase details')%> +

    + <%= raw _('When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions.')%> +
    +
    + <%= f.hidden_field :template_id, value: @template.id%> + + + + + + + + + + + + + +
    <%= _('Title') %><%= f.text_field :title, + as: :string, + class: "text_field has-tooltip", "data-toggle" => "tooltip", "title" => _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP') %>
    <%= _('Order of display') %><%= f.number_field :number, in: 1..5, class: "number_field has-tooltip", "data-toggle" => "tooltip", title: _('This allows you to order the phases of your template.') %>
    <%= _('Description') %> +
    + <%= text_area_tag("phase-desc","" , class: "tinymce") %> + <%= tinymce :content_css => asset_path('application.css') %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "phase_desc_popover", rel: "popover", "data-html" => "true", "data-content" => _("Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer."))%> +
    +
    +
    +
    + + +
    + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Cancel'), admin_template_template_path(@template), class: "btn cancel" %> +
    + + <%end%> +
    +
    +
    +
    \ No newline at end of file diff --git a/app/views/phases/admin_preview.html.erb b/app/views/phases/admin_preview.html.erb new file mode 100644 index 0000000..59ce2d0 --- /dev/null +++ b/app/views/phases/admin_preview.html.erb @@ -0,0 +1,59 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> + +

    + <%= @template.title %> + +
    + <%= link_to _('Back to edit view'), + admin_show_phase_path(id: @phase.id, edit: "true"), + class: 'btn btn-primary' %> + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
    +

    + +
    + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @template, active: @phase.id} %> + + +
    +
    + <% sections = @phase.sections %> + <% sections.order(:number).each do |section| %> +
    + +
    +
    + <%= raw section.description %> +
    +
    + <% last_question_id = section.questions.order("number DESC").first.id%> + + <% section.questions.order("number").each do |question| %> + + <%= render partial: 'questions/preview_question', locals: {question: question}%> + <% if last_question_id == question.id then %> +
    + <% else %> +
    + <% end %> + + <% end %> +
    +
    +
    + <% end %> +
    +
    \ No newline at end of file diff --git a/app/views/phases/admin_show.html.erb b/app/views/phases/admin_show.html.erb new file mode 100644 index 0000000..60dc90d --- /dev/null +++ b/app/views/phases/admin_show.html.erb @@ -0,0 +1,69 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> +<% javascript 'admin.js' %> + +<%= tinymce :content_css => asset_path('application.css') %> + +

    + <%= @phase.template.title %> + +
    + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
    +

    + +
    + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @phase.template, active: @phase.id, edit: @edit, current: @current} %> + + +
    +
    + + +
    +
    + + +
    + <%= render partial: "phases/show_phase", locals: {phase: @phase}%> +
    + <% if @phase.modifiable && @edit %> + + <% end %> +
    +
    + + + <% @sections.order("number ASC").each do |section| %> + <% if @edit && section.modifiable %> + <%= render partial: 'sections/edit_section', locals: {section: section, edit: @edit, phase: @phase} %> + <% else %> + <%= render partial: 'sections/show_section', locals: {section: section}%> + <% end %> + <% end %> + +
    +
    + + +<% if @edit || @phase.template.customization_of.present? %> + + + + +
    +
    + <%= link_to _('Add section'),'#', id: 'add_section_button', class: 'btn btn-primary' %> +
    +
    +<% end %> + + diff --git a/app/views/phases/edit.html.erb b/app/views/phases/edit.html.erb new file mode 100644 index 0000000..5a4c267 --- /dev/null +++ b/app/views/phases/edit.html.erb @@ -0,0 +1,118 @@ +<%- model_class = Plan -%> +<% javascript('plans.js') %> +<% javascript('answers/status.js') %> +<% javascript ('notes/index.js') %> + + + +<%= render :partial => "/plans/plan_title", locals: {plan: @plan} %> + + +
    + <%= render :partial => "/plans/progress", locals: { plan: @plan } %> +
    + + +<%= render :partial => "/plans/plan_nav_tabs", locals: {plan: @plan, active: @phase.title} %> + + +
    + +
    + <% @phase.sections.order(:number).each do |section| %> + + <% sectionid = section.id %> + +
    + + + + +
    +
    + <%= raw section.description %> +
    + +
    + + + + + + + +
    + <% section.questions.each do |question| %> + <% if question.id == session[:question_id_comments].to_i then id_css = "current_question" end %> +
    + + <% guidances = @question_guidance[question.id] %> + + <%= render partial: 'answer_form', + locals: { + plan: @plan, + question: question, + question_guidances: guidances, + last_question_id: section.questions.last.id, + readonly: @readonly + } + %> +
    + <% end %> +
    +
    +
    +
    + + + + + <% end %> +
    +
    + + + +<%= render :partial => "plans/export", locals: {plan: @plan, plan_data: @plan_data, phase: @phase } %> diff --git a/app/views/plans/_add_comment.html.erb b/app/views/plans/_add_comment.html.erb deleted file mode 100644 index 0d8aa49..0000000 --- a/app/views/plans/_add_comment.html.erb +++ /dev/null @@ -1,20 +0,0 @@ - - -<% @new_comment = Comment.new %> - -<%= form_for :new_comment, :url => {:controller => :comments, :action => :create } , :html=>{:method=>:post, :id => "new_comment_form_#{questionId}", :class => "add_comment_form"} do |f| %> - <%= f.hidden_field :user_id, :value => current_user.id %> - <%= f.hidden_field :question_id, :value => questionId %> - <%= f.hidden_field :plan_id, :value => planId %> - - <%= text_area_tag("#{questionId}new_comment_text".to_sym, "" , class: "tinymce") %> -
    - <% question = Question.find(questionId)%> - -
    - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary new_comment_submit_button" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_answer_form.html.erb b/app/views/plans/_answer_form.html.erb deleted file mode 100644 index 5f262ba..0000000 --- a/app/views/plans/_answer_form.html.erb +++ /dev/null @@ -1,269 +0,0 @@ - -<% answer = @plan.answer(question.id) %> - -
    - - <% q_format = question.question_format%> - - <% if readonly != "always" then %> -
    > - <%= semantic_form_for answer, :url => {:controller => :answers, :action => :create }, :html=>{:method=>:post}, :remote => true do |f| %> - <%= f.inputs do %> - <%= f.input :plan_id, :as => :hidden %> - <%= f.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } %> - <%= f.input :question_id, :as => :hidden, :input_html => { :class => "question_id" } %> - - - - <%= raw question.text %> - - - <% suggested_answer = question.suggested_answers.find_by_organisation_id(@plan.project.organisation_id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> -
    - - <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> - <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> - <%end%> - -
    -

    - <%= raw suggested_answer.text %> -

    -
    -
    - <% end %> - - - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> - <% options = question.options.order("number") %> - - <% if q_format.title == t("helpers.checkbox") then %> - <% if readonly then %> - <%= f.input :options, :as => :check_boxes, :collection => options, :label => false, input_html => { :disabled => true, :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :check_boxes, :collection => options, :label => false, :input_html => { :id => "options-#{question.id}" } %> - <% end %> - - <% elsif q_format.title == t("helpers.multi_select_box") then %> - <% if readonly then %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => true, :disabled => true , :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => true , :id => "options-#{question.id}" } %> - <% end %> - - <% elsif q_format.title == t("helpers.radio_buttons") then%> -
      - <% options.each do |op| %> -
    1. - <% if answer.option_ids[0] == op.id then%> - <% if readonly then %> - <%= f.radio_button :option_ids, op.id, :checked => true, disabled: true, id: "answer_option_ids_#{op.id}"%> - <% else %> - <%= f.radio_button :option_ids, op.id, :checked => true, id: "answer_option_ids_#{op.id}"%> - <% end %> - <%else%> - <% if readonly then %> - <%= f.radio_button :option_ids, op.id, :checked => false, disabled: true, id: "answer_option_ids_#{op.id}"%> - <% else %> - <%= f.radio_button :option_ids, op.id, :checked => false, id: "answer_option_ids_#{op.id}"%> - <% end %> - <%end%> - <%= op.text %>
    2. - <%end%> -
    - - <% elsif q_format.title == t("helpers.dropdown") then%> - <% if readonly then %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => false, :disabled => true, :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => false, :id => "options-#{question.id}" } %> - <% end %> - <% end %> - - - - - <% if question.option_comment_display == true then%> - <%= label_tag("answer-text-#{question.id}".to_sym, t("helpers.comment")) %> - <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> - <%end%> - - - <% elsif q_format.title == t("helpers.text_field") then %> - <%= text_field_tag("answer-text-#{question.id}".to_sym, strip_tags(answer.text), class: "question_text_field") %> - - <% elsif q_format.title == t("helpers.text_area") then%> - <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> - <% end %> - - <% end %> - - - <%= f.actions do %> - <% if readonly then %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"}, :input_html => { :disabled => true } %> - <% else %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"} %> - <% end %> - - <% end %> - <% end %> -
    - <% end %> - - -
    > -

    <%= question.text %>

    -
    - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") %> -
      - <% if answer.options.is_a? Option then %> -
    • <%= answer.options.text %>
    • - <% else %> - <% answer.options.each do |o| %> -
    • <%= o.text %>
    • - <% end %> - <% end %> -
    - <% end %> -
    - <%= raw answer.text %> -
    -
    -
    - - <% if answer.created_at.nil? then %> - <%= t("helpers.notanswered") %> - <% else %> - <%= t("helpers.answered_by")%><%= answer.created_at %><%= t("helpers.answered_by_part2")%><%= answer.user.name %> - <% end %> - - -
    - - - -
    - -
    - <% @comments = Comment.where("question_id = ? AND plan_id = ?", question.id, answer.plan_id ) %> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <% @question_guidances = @plan.guidance_for_question(question) %> -
      - <% if (!question.guidance.nil? && question.guidance != "") || @question_guidances.count > 0 then %> - - <% css_style_comment_div = "display: none;"%> - <% css_style_guidance_div = ""%> -
    • - <%= link_to t("helpers.guidance_accordion_label"), "#", :class => "guidance_accordion_button" %> -
    • -
    • - <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> - <%= link_to comments_label_with_count , "#", :class => "comments_accordion_button" %> - <%else%> - <%= link_to t("helpers.add_comment_accordion_label"), "#", :class => "comments_accordion_button" %> - <%end%> -
    • - <%else%> - - <% css_style_comment_div = ""%> - <% css_style_guidance_div = "display: none;"%> -
    • - <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> -

      <%= comments_label_with_count %>

      - <%else%> -

      <%= t("helpers.add_comment_accordion_label") %>

      - <%end%> -
    • - <%end%> -
    -
    - - - -
    -
    - - <% if !question.guidance.nil? && question.guidance != "" then %> - - <% end %> - - <% @question_guidances.each_pair do |group,themes| %> - <% themes.each_pair do |theme,guidances| %> - <% guidances.each do |guidance| %> - - <% end %> - <% end %> - <% end %> - - -
    -
    - - -
    - <%= render :partial => "comments", locals: {questionId: question.id, plan_id: answer.plan_id }%> - -
    - - - -
    - -<% if last_question_id == question.id then %> -
    -<% else %> -
    -<% end %> diff --git a/app/views/plans/_answer_form_ro.html.erb b/app/views/plans/_answer_form_ro.html.erb new file mode 100644 index 0000000..e035e1c --- /dev/null +++ b/app/views/plans/_answer_form_ro.html.erb @@ -0,0 +1,51 @@ + +<% answer = @plan.answer(question.id) %> + +
    + + <% q_format = question.question_format%> + +
    +

    <%= question.text %>

    + +
    + <% if q_format.title == "Check box" || q_format.title == "Multi select box" || + q_format.title == "Radio buttons" || q_format.title == "Dropdown" %> +
      + <% if answer.question_options.is_a? Array then %> +
    • <%= answer.question_options.text %>
    • + <% else %> + <% answer.question_options.each do |o| %> +
    • <%= o.text %>
    • + <% end %> + <% end %> +
    + <% end %> + +
    + <%= raw answer.text %> +
    +
    +
    + + <% if answer.created_at.nil? then %> + <%= _('Not answered yet') %> + <% else %> + <%= _('Answered')%><%= answer.created_at %><%= _(' by')%><%= answer.user.name %> + <% end %> + + + +
    + + +<% if last_question_id == question.id then %> +
    +<% else %> +
    +<% end %> diff --git a/app/views/plans/_archive_comment.html.erb b/app/views/plans/_archive_comment.html.erb deleted file mode 100644 index 03ba05c..0000000 --- a/app/views/plans/_archive_comment.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - -<%= form_for(comment, :url => {:controller => :comments, :action => :archive } , :html => { :method => :put, :class => "archive_comment_form", :id => "archive_comment_form_#{comment.id}"}) do |f| %> - <%= f.hidden_field :id, :value => comment.id %> - <%= f.hidden_field :archived_by, :value => current_user.id %> - - <%= render :partial => "view_comment", locals: {comment: comment} %> - - <% if current_user.id == comment.user_id then %> - <%= t('helpers.comments.archive_own_comment_question')%> - <% button_label = t("helpers.comments.archive_own_comment_button_label") %> - <% else%> - <%= t("helpers.comments.archive_comment_question")%> - <% button_label = t("helpers.comments.archive_comment_button_label") %> - <%end%> - - -
    - <% question = Question.find(comment.question_id)%> - <%= hidden_field_tag :plan_id, comment.plan_id, :class => "plan_id" %> - <%= hidden_field_tag :comment_id, comment.id, :class => "comment_id" %> - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= f.submit button_label, :class => "btn btn-primary archive_comment_submit_button" %> - <%= hidden_field_tag :comment_id, comment.id, :class => "comment_id" %> - <%= link_to t("helpers.submit.cancel"), "#", :class => "cancel_archive_comment btn cancel" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_available_templates.html.erb b/app/views/plans/_available_templates.html.erb new file mode 100644 index 0000000..59eb6fa --- /dev/null +++ b/app/views/plans/_available_templates.html.erb @@ -0,0 +1,20 @@ +<%= _('Which DMP template would you like to use?') %> + + + + + +
    + <%= _('We found multiple DMP templates corresponding to your funder.') %> +
    + + \ No newline at end of file diff --git a/app/views/plans/_comments.html.erb b/app/views/plans/_comments.html.erb deleted file mode 100644 index dc21608..0000000 --- a/app/views/plans/_comments.html.erb +++ /dev/null @@ -1,35 +0,0 @@ - - - - -<% @comments = Comment.where("question_id = ? AND plan_id = ?", questionId, plan_id) %> -<%= hidden_field_tag :question_id, questionId, :class => "question_id" %> - -<% if @comments.count > 0 then%> - -
    - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> - -
    -
    -
    - - <%= render :partial => "list_comments", locals: {comments: @comments}%> -
    -
    - -
    - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> -
    -
    -
    - - - -<% else%> - <%= t("helpers.comments.add_comment_text")%> - <%= render :partial => "add_comment", locals: {questionId: questionId, planId: plan_id}%> -<% end%> diff --git a/app/views/plans/_edit_comment.html.erb b/app/views/plans/_edit_comment.html.erb deleted file mode 100644 index 5ea6c8b..0000000 --- a/app/views/plans/_edit_comment.html.erb +++ /dev/null @@ -1,18 +0,0 @@ - - -<%= form_for(comment, :url => {:controller => :comments, :action => :update } , :html => { :method => :put, :class => "edit_comment_form", :id=> "edit_comment_form_#{comment.id}"}) do |f| %> - <%= f.hidden_field :id, :value => comment.id %> - - <%= text_area_tag("#{comment.id}_comment_text".to_sym, comment.text , class: "tinymce") %> -
    - - -
    - <% question = Question.find(comment.question_id)%> - <%= hidden_field_tag :plan_id, comment.plan_id, :class => "plan_id" %> - <%= hidden_field_tag :comment_id, comment.id, :class => "comment_id" %> - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary edit_comment_submit_button" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_export.html.erb b/app/views/plans/_export.html.erb index 6c0e8de..cd7ed05 100644 --- a/app/views/plans/_export.html.erb +++ b/app/views/plans/_export.html.erb @@ -1,9 +1,9 @@ - diff --git a/app/views/plans/_form.html.erb b/app/views/plans/_form.html.erb index b7424e0..4c4404a 100644 --- a/app/views/plans/_form.html.erb +++ b/app/views/plans/_form.html.erb @@ -26,7 +26,7 @@
    <%= f.submit nil, :class => 'btn btn-primary' %> - <%= link_to t('.cancel', :default => t("helpers.links.cancel")), - plans_path, :class => 'btn' %> + <%= link_to _('helpers.links.cancel'), + plans_path, :class => 'btn' %>
    <% end %> diff --git a/app/views/plans/_guidance_settings.html.erb b/app/views/plans/_guidance_settings.html.erb index 946c2e7..7b48331 100644 --- a/app/views/plans/_guidance_settings.html.erb +++ b/app/views/plans/_guidance_settings.html.erb @@ -1,7 +1,7 @@ +
    + + <% end %>
    - <%= tinymce :content_css => asset_path("application.css"), :setup => "function(editor){editor.on('change', function(e){$.fn.check_textarea(editor)});}" %> + <%= tinymce :content_css => asset_path('application.css') %> -<%= render :partial => "export", locals: {plan: @plan} %> +<%= render :partial => "export", locals: {plan: @plan, phase: @phase} %> <% session.delete(:question_id_comments)%> diff --git a/app/views/plans/export.docx.caracal b/app/views/plans/export.docx.caracal deleted file mode 100644 index e6b4fbb..0000000 --- a/app/views/plans/export.docx.caracal +++ /dev/null @@ -1,251 +0,0 @@ -#----------------------------------------------------- -# page settings -#----------------------------------------------------- - -docx.page_numbers true do - align :center -end - -docx.font do - name 'Arial' -end - -docx.p do - size 32 -end - - -#--------------------------------------------- -# Structure for docx format -#--------------------------------------------- - -docx.h1 @exported_plan.plan.project.title.upcase, font: 'Arial', color: '000000' -docx.h2 @exported_plan.plan.title.upcase, font: 'Arial', color: '000000' - -#---- PLAN ADMIN DETAILS ----- -if @exported_plan.admin_details.present? - docx.p - docx.h3 'Admin Details'.upcase , italic: false, font: 'Arial', color: '000000' - @exported_plan.admin_details.each do |field| - value = @exported_plan.send(field) - label = "helpers.plan.export.#{field}" - if value.present? - docx.p do - text I18n.t(label), bold: true, color: '000000' - text ': ', bold: true, color: '000000' - text value - end - end - end -end - - -#---- PLAN SECTIONS, QUESTIONS AND ANSWERS ----- -@exported_plan.sections.each do |section| - docx.p - docx.h3 section.title.upcase, italic: false, font: 'Arial', color: '000000' - - @exported_plan.questions_for_section(section.id).each do |question| - docx.p strip_tags(question.text.gsub(/
  • /, ' * ')), bold: true - - answer = @exported_plan.plan.answer(question.id, false) - if answer.nil? - docx.p 'Question not answered', italic: true - else - q_format = question.question_format - if q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") || - q_format.title == I18n.t("helpers.radio_buttons") || q_format.title == I18n.t("helpers.dropdown") then - answer.options.each do |option| - docx.ul do - if !option.text.nil? - li option.text - end - end - end - end - - if !answer.text.nil? && question.option_comment_display == true then - search_answer = Nokogiri::HTML::DocumentFragment.parse "
    " - search_answer.at(".//div").inner_html = answer.text - - if search_answer.css('table').present? then - table_content = search_answer.css('table').css('tbody') - - if table_content.size > 0 then - table_array = Array.new - - table_content.css('tr').each do |tr| - row_th_array = Array.new - row_td_array = Array.new - - if tr.search('th') then - tr.search('th').each do |cell| - row_th_array << cell.text.to_s - end - end - - if tr.search('td') then - tr.search('td').each do |td_cell| - if !td_cell.text.to_s.blank? then - new_val = Nokogiri::HTML::DocumentFragment.parse "

    " - new_val.at(".//p").inner_html = td_cell - td_tags = new_val.at_css('td').children.map {|x| x.name.strip} - td_text = new_val.at_css('td').children.map {|x| x.text.strip} - - start_c = 0 - end_c = td_tags.size - - c1 = Caracal::Core::Models::TableCellModel.new do - while start_c < end_c do - p do - #-- TEXT - if td_tags[start_c] == 'text' then - text td_text[start_c] - else - #-- LINK - if td_tags[start_c] == 'a' then - l_address = "" - l_text = td_text[start_c] - #-- GET HREF - td_cell.search('a').each do |link| - if link.content == td_text[start_c] then - l_address = link["href"] - end - end - link td_text[start_c], l_address - #-- BOLD TEXT - else - if td_tags[start_c] == 'strong' && td_text[start_c] != "" then - text td_text[start_c], bold: true - text ' ' - #-- ITALIC TEXT - else - if td_tags[start_c] == 'em' && td_text[start_c] != "" then - text td_text[start_c], italic: true - text ' ' - end - end - end - end - end - start_c += 1 - end - end - row_td_array << c1 - else - row_td_array << td_cell.text.to_s - end - end - end - - #--- check if all cells are empty - if row_td_array.size > 0 then - if row_td_array.all?(&:blank?) then - row_td_array = [] - end - end - - if !row_th_array.empty? then - table_array << row_th_array - end - if !row_td_array.empty? then - table_array << row_td_array - end - - end - - #--- build the table layout - docx.table table_array, border_size: 4 do - cell_style rows[0], bold: true, background: 'fbb400' - cell_style cells, size: 18, margins: { top: 100, bottom: 0, left: 100, right: 100 } - end - - end - - else - higher_level = search_answer.search('div.container').children.map {|x| x.name.strip} - all_text = search_answer.search('div.container').children.map {|x| x.inner_html.strip} - high_count = 0 - high_end_count = higher_level.size - - while high_count < high_end_count do - - if higher_level[high_count] == 'p' then - inner_txt_with_tags = Nokogiri::HTML::DocumentFragment.parse "

    " - inner_txt_with_tags.at(".//p").inner_html = all_text[high_count] - tags_type = inner_txt_with_tags.at_css('p').children.map {|x| x.name.strip} - inner_txt = inner_txt_with_tags.at_css('p').children.map {|x| x.text.strip} - - start_count = 0 - end_counter = tags_type.size - - docx.p do - while start_count < end_counter do - text_val = inner_txt[start_count].to_s - #-- TEXT - if tags_type[start_count] == 'text' && text_val != "" then - text text_val - text ' ' - #-- LINK - else - if tags_type[start_count] == 'a' && text_val != "" then - l_text = text_val - l_address = "" - # all links - search_answer.search('a').each do |link| - if link.content == text_val then - l_address = link["href"] - end - end - link text_val, l_address - #-- BOLD TEXT - else - if tags_type[start_count] == 'strong' && text_val != "" then - text text_val, bold: true - text ' ' - #-- ITALIC TEXT - else - if tags_type[start_count] == 'em' && text_val != "" then - text text_val, italic: true - text ' ' - end - end - end - end - start_count +=1 - end - end - #-- END OF P - else - if higher_level[high_count] == 'ul' then - ul_text = search_answer.search('ul').children.map {|x| x.text.strip} - docx.ul do - ul_text.each do |txt| - if !txt.blank? - li txt - end - end - end - else - if higher_level[high_count] == 'ol' then - ol_text = search_answer.search('ol').children.map {|x| x.text.strip} - docx.ol do - ol_text.each do |txt| - if !txt.blank? - li txt - end - end - end - end - end - end - - high_count += 1 - end - end - end - end - #-- add a new line - docx.p - end -end diff --git a/app/views/plans/export.docx.erb b/app/views/plans/export.docx.erb new file mode 100644 index 0000000..be267a8 --- /dev/null +++ b/app/views/plans/export.docx.erb @@ -0,0 +1,47 @@ +

    <%= @plan.title %>

    +

    <%= @plan.template.title %>

    + +<% details = @exported_plan.admin_details %> +<% if details.present? %> +

    <%= _('Admin Details') %>

    + <% details.each do |field| %> + <% value = @exported_plan.send(field) %> +

    + <%= admin_field_t(field.to_s) %>: + <%= value.present? ? value : _('-') %> +

    + <% end %> +<% end %> + + + +<% @exported_plan.sections.each do |section| %> + <% questions = @exported_plan.questions_for_section(section.id) + if questions.present? + %> +

    <%= section.title %>

    + <% questions.each do |question| %> +

    + <%= raw question.text %> +

    + <% answer = @plan.answer(question.id, false) %> + <% if answer.nil? %> +

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

    + <% else %> + <% q_format = question.question_format %> + <% if q_format.option_based? %> +
      + <% answer.question_options.each do |option| %> +
    • <%= raw option.text %>
    • + <% end %> +
    + <% if question.option_comment_display %> + <%= raw answer.text %> + <% end %> + <% else %> + <%= raw answer.text %> + <% end %> + <% end%> + <% end %> + <% end %> +<% end %> diff --git a/app/views/plans/export.html.erb b/app/views/plans/export.html.erb index fc991ec..27a6b1b 100644 --- a/app/views/plans/export.html.erb +++ b/app/views/plans/export.html.erb @@ -1,77 +1,76 @@
    -

    <%= @plan.project.title %>

    -

    <%= @plan.version.phase.title %>

    +

    <%= @plan.title %>

    +

    <%= @plan.template.title %>

    <% details = @exported_plan.admin_details if details.present? %> -

    <%= t('org_admin.admin_details') %>

    +

    <%= _('Admin Details') %>

    - - + + <% details.each do |field| value = @exported_plan.send(field) - if value.present? %> - - + + - <% end %> <% end %>
    <%= t('helpers.title')%><%= t('helpers.desc')%><%= _('Title')%><%= _('Description')%>

    - <%= t("helpers.plan.export.#{field}") -%>

    <%= value -%>

    - <%= admin_field_t(field.to_s) -%>

    <%= value.present? ? value : _('-') %>
    - <% end %> + <% end %> <% @exported_plan.sections.each do |section| %> -

    <%= section.title %>

    - - - - - - - - - <% questions = @exported_plan.questions_for_section(section.id) %> - <% questions.each do |question| %> + <% questions = @exported_plan.questions_for_section(section.id) + if questions.present? %> +

    <%= section.title %>

    +
    <%= t('helpers.questions_label')%><%= t('helpers.answers_label')%>
    + + + + + + + + <% questions.each do |question| %> <% end %> - -
    <%= _('Questions')%><%= _('Answers')%>

    - <%= raw question.text %>

    <% answer = @plan.answer(question.id, false) %> - <% if answer.nil? then %> -

    Question not answered.

    + <% if answer.nil? %> +

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

    <% else %> <% q_format = question.question_format %> - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || - q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> + <% if q_format.option_based? %>
      - <% answer.options.each do |option| %> + <% answer.question_options.each do |option| %>
    • <%= option.text %>
    • <% end %>
    - <% if question.option_comment_display == true then%> + <% if question.option_comment_display == true %> <%= raw answer.text %> <% end %> - <%else%> + <% else%> <%= raw answer.text %> - <%end%> + <% end%> <% end %>
    - <% end %> + + + <% end %> + <% end %>
    diff --git a/app/views/plans/export.pdf.erb b/app/views/plans/export.pdf.erb index 77d68cb..b9ab084 100644 --- a/app/views/plans/export.pdf.erb +++ b/app/views/plans/export.pdf.erb @@ -3,11 +3,7 @@ - <% if @plan.project.dmptemplate.phases.count > 1 then %> - <%= "#{@plan.project.title} - #{@plan.title}" %> - <% else %> - <%= @plan.project.title %> - <% end %> + <%= @plan.title %> + + +

    <%= @plan.title %>

    + <% @exported_plan.admin_details.each do |field| + value = @exported_plan.send(field) + if value.present? + %> +

    <%= t("helpers.plan.export.#{field}") -%> <%= value -%>

    + <% end %> + <% end %> + + <% @exported_plan.sections.each do |section| %> +

    <%= section.title %>

    + <% questions = @exported_plan.questions_for_section(section.id) %> + <% questions.each_with_index do |question, idx| %> +
    + <% unless idx == 0 && question.text == section.title %> +

    <%= raw question.text %>

    + <% end %> + <% answer = @plan.answer(question.id, false) %> + <% if answer.nil? then %> +

    <%= t('helpers.plan.export.pdf.question_not_answered') -%>

    + <% else %> + <% q_format = question.question_format%> + + <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || + q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> +
      + <% answer.options.each do |option| %> +
    • <%= option.text %>
    • + <% end %> +
    + + <% if question.option_comment_display == true then%> + <% if !answer.text.nil? then %> + <%= raw answer.text.gsub(/(\s||<\/td>| )*(<\/tr>|)/,"") %> + <%end%> + <%end%> + <%else%> + + <% if !answer.text.nil? then %> + <%= raw answer.text.gsub(/(\s||<\/td>| )*(<\/tr>|)/,"") %> + <%end%> + <% end %> + <% end %> +
    + <% end %> + <% end %> + + \ No newline at end of file diff --git a/app/views/static_pages/public_plans.html.erb b/app/views/static_pages/public_plans.html.erb new file mode 100644 index 0000000..6a14750 --- /dev/null +++ b/app/views/static_pages/public_plans.html.erb @@ -0,0 +1,39 @@ +<%- model_class = Plan -%> +

    + <%= raw _('Public DMPs') %> +

    + + +<% if @plans.count > 0 %> +

    + <%= _('Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines.') %> +

    + + + + + + + + + + + + + <% @plans.each do |plan| %> + + <% ['non_link_name', 'template', 'organisation', 'owner'].each do |column| %> + <%= plan_list_column_body(column, plan) %> + <% end %> + + + + + <% end %> + +
    <%= _('Name') %><%= _('Template') %><%= _('Organization') %><%= _('Owner') %>
    +<% else %> +

    + <%= _("There are no public DMPs.")%> +

    +<% end %> diff --git a/app/views/static_pages/roadmap.html.erb b/app/views/static_pages/roadmap.html.erb index 311ca4b..8ee60c7 100644 --- a/app/views/static_pages/roadmap.html.erb +++ b/app/views/static_pages/roadmap.html.erb @@ -14,35 +14,35 @@

    - <%= t("roadmap_page.title")%> + <%= _('Future plans')%>

    - <%= raw t("roadmap_page.body_text_tab_1_html", - organisation_email: Rails.configuration.branding[:organisation][:email], - organisation_abbreviation: Rails.configuration.branding[:organisation][:abbreviation], - application_name: Rails.configuration.branding[:application][:name], - application_url: Rails.configuration.branding[:application][:url], - application_version: Rails.configuration.branding[:application][:version], - application_release_notes_url: Rails.configuration.branding[:application][:release_notes_url])%> + <%= raw _("

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    ") % { + :organisation_email => Rails.configuration.branding[:organisation][:email], + :organisation_abbreviation => Rails.configuration.branding[:organisation][:abbreviation], + :application_name => Rails.configuration.branding[:application][:name], + :application_url => Rails.configuration.branding[:application][:url], + :application_version => Rails.configuration.branding[:application][:version], + :application_release_notes_url => Rails.configuration.branding[:application][:release_notes_url] } %>
    - <%= raw t("roadmap_page.body_text_tab_2_html", + <%= raw _("

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    ") % { organisation_name: Rails.configuration.branding[:organisation][:name], organisation_email: Rails.configuration.branding[:organisation][:email], organisation_url: Rails.configuration.branding[:organisation][:url], organisation_abbreviation: Rails.configuration.branding[:organisation][:abbreviation], application_name: Rails.configuration.branding[:application][:name], application_url: Rails.configuration.branding[:application][:url], - application_user_group_subscription_url: Rails.configuration.branding[:application][:user_group_subscription_url])%> + application_user_group_subscription_url: Rails.configuration.branding[:application][:user_group_subscription_url] } %>
    \ No newline at end of file diff --git a/app/views/static_pages/termsuse.html.erb b/app/views/static_pages/termsuse.html.erb index bf943a1..b7a70f8 100644 --- a/app/views/static_pages/termsuse.html.erb +++ b/app/views/static_pages/termsuse.html.erb @@ -1,10 +1,10 @@

    - <%= t('terms_page.title')%> + <%= _('Terms of use')%>

    -<%= raw t('terms_page.body_text_html', - legal_entity: Rails.configuration.branding[:legal_entity], - organisation_name: Rails.configuration.branding[:organisation][:name], - organisation_abbreviation: Rails.configuration.branding[:organisation][:abbreviation], - organisation_url: Rails.configuration.branding[:organisation][:url], - application_name: Rails.configuration.branding[:application][:name])%> +<%= raw _("

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    ") % { + :legal_entity => Rails.configuration.branding[:legal_entity], + :organisation_name => Rails.configuration.branding[:organisation][:name], + :organisation_abbreviation => Rails.configuration.branding[:organisation][:abbreviation], + :organisation_url => Rails.configuration.branding[:organisation][:url], + :application_name => Rails.configuration.branding[:application][:name] } %> diff --git a/app/views/templates/_admin_nav_tabs.html.erb b/app/views/templates/_admin_nav_tabs.html.erb new file mode 100644 index 0000000..0399cc3 --- /dev/null +++ b/app/views/templates/_admin_nav_tabs.html.erb @@ -0,0 +1,38 @@ + + + diff --git a/app/views/templates/_edit_annotations.html.erb b/app/views/templates/_edit_annotations.html.erb new file mode 100644 index 0000000..8273f4d --- /dev/null +++ b/app/views/templates/_edit_annotations.html.erb @@ -0,0 +1,100 @@ + + +<%= form_for(question, url: admin_update_question_path(question), html: { method: :put}) do |f| %> +
    + + <%= f.hidden_field :id,{ class: "quest_id" } %> + + + + + + + + + + + + + + + + + + + + + + + +
    <%= _('Question number')%><%= question.number %> +
    +
    <%= _('Question text')%><%= raw question.text %> +
    +
    + <% q_format = question.question_format %> + <% if q_format.title == _('Check box') || q_format.title == _('Multi select box') || q_format.title == _('Radio buttons') || q_format.title == _('Dropdown') %> +
      + <% if question.question_options.is_a? QuestionOption %> +
    • - <%= question.question_options.text %>
    • + <% else %> + <% if !question.question_options.to_a.nil? %> + <% question.question_options.to_a.sort_by{|op| op['number']}.each do |o| %> +
    • - <%= o.text %>
    • + <% end %> + <% end %> + <% end %> +
    + <% end %> +
    +
    <%= _('example answer')%> +
    + <% annotations = question.annotations.where(org_id: current_user.org_id).where(type: Annotation.types[:example_answer]).order(:created_at).first %> + <% if annotations.nil? %> + <% annotations = question.annotations.build %> + <% end %> + <%= f.fields_for :annotations, annotation do |s|%> + <%= s.hidden_field :org_id, value: current_user.org.id %> +
      +
    • <%= s.text_area :text, rows: 5 %>
    • +
    + <% end %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "suggested_answer_popover", rel: "popover", "data-html" => "true", "data-content" => _('You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted.'))%> +
    +
    +
    +
    <%= _('Guidance')%> +
    + <%= text_area_tag("question-guidance-#{question.id}", question.guidance , class: "tinymce") %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "question_guidance_popover", rel: "popover", "data-html" => "true", "data-content" => _("Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text."))%> +
    +
    +
    +
    +
    + +
    + <%= f.submit _('Save'), class: "btn btn-primary" %> + <% if !question.section.phase.template.published? %> + <%= link_to _('Delete'), admin_destroy_question_path(question_id: question.id), + confirm: _("You are about to delete '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-primary"%> + <% end %> + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Cancel'), "#", class: "btn cancel cancel_edit_question" %> +
    +
    + + + +<%= render partial: "guidances/guidance_display", locals: {question: question} %> +<% end %> diff --git a/app/views/templates/_edit_template.html.erb b/app/views/templates/_edit_template.html.erb new file mode 100644 index 0000000..a660e7b --- /dev/null +++ b/app/views/templates/_edit_template.html.erb @@ -0,0 +1,59 @@ + + +<%= form_for(template, url: admin_update_template_path(template), html: { method: :put}) do |f| %> +
    + + + + + + + + + + + + + + + + + + + + + +
    <%= _('Title') %><%= f.text_field :title, as: :string, + class: 'text_field has-tooltip', 'data-toggle' => "tooltip", title: _('Please enter a title for your template.') %>
    <%= _('Description') %> +
    + <%= text_area_tag("template-desc", template.description, class: "tinymce") %> +
    +
    + <%= link_to( image_tag('help_button.png'), '#', class: 'template_desc_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences'))%> +
    +
    +
    <%= _('Status') %> + <% if hash[:live].nil? %> + <%= _('Unpublished') %> + + <% elsif hash[:current].dirty? %> + <%= _('You have un-published changes') %> + + <% else %> + <%= _('Published') %> + <% end %> +
    <%= _('Created at') %> + <%= l template.created_at.to_date, formats: :short %> +
    <%= _('Last updated') %> + <%= l template.updated_at.to_date, formats: :short %> +
    + + +
    + <%= f.submit _('Save'), class: 'btn btn-primary' %> + <%= link_to _('Cancel'), admin_template_template_path(template), class: 'btn cancel' %> +
    + +
    + +<% end %> \ No newline at end of file diff --git a/app/views/templates/_show_phases_sections.html.erb b/app/views/templates/_show_phases_sections.html.erb new file mode 100644 index 0000000..ec365d8 --- /dev/null +++ b/app/views/templates/_show_phases_sections.html.erb @@ -0,0 +1,61 @@ + + +
    + +
    +

    <%= raw phase.description %>

    +
    + + + +
    + + + <% if phase_hash[:sections].length > 0 %> + <%= link_to _('Preview'), admin_preview_phase_path(id: phase.id), class: 'btn btn-primary'%> + <% end %> + <% if template == current && phase.modifiable %> + <%= link_to _('Delete'), admin_destroy_phase_path(phase_id: phase.id), + confirm: _("You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?") % { :phase_title => phase.title }, method: :delete, class: "btn btn-primary"%> + <% b_label = _('Edit phase')%> + <% else %> + <% b_label = _('View phase')%> + <% end %> + <%= link_to b_label, admin_show_phase_path(id: phase.id, edit: (b_label == _('Edit phase'))), class: "btn btn-primary" %> + +
    + <% if phase_hash[:sections].present? %> + + + + + + + + + <% (phase_hash[:sections].values.sort_by { |key| key[:data][:number] }).each do |section| %> + <% if section.present? %> + + + + + <% end %> + <% end %> + +
    <%= _('Sections')%><%= _('Questions')%>
    +

    <%= section[:data].title %>

    +
    + <% if section[:questions].present? %> +
      + <% (section[:questions].values.sort_by { |key| key[:data][:number] }).each do |question| %> +
    • + - <%= raw question[:data].text %> +
    • + <% end %> +
    + <% end %> +
    + <% end %> + + +
    diff --git a/app/views/templates/_show_template.html.erb b/app/views/templates/_show_template.html.erb new file mode 100644 index 0000000..fed7740 --- /dev/null +++ b/app/views/templates/_show_template.html.erb @@ -0,0 +1,50 @@ + + +<% if template == current then %> +

    + <% if template.customization_of.nil? %> +
    + <%= link_to _('Edit template details'), '# ', class: "btn btn-primary", id: "edit_template_button"%> +
    + <% end %> +

    +<% end %> +
    + + + + + + + + + + + + + + + + + + + + + + +
    <%= _('Title') %><%= template.title %>
    <%= _('Description') %><% if !template.description.nil? && template.description != "" then %> + <%= raw template.description %> + <% else %> + - + <% end %> +
    <%= _('Status') %> + <% if hash[:live].nil? %> + <%= _('Unpublished') %> + + <% elsif hash[:current].dirty? %> + <%= _('You have un-published changes') %> + + <% else %> + <%= _('Published') %> + <% end %> +
    <%= _('Created at') %><%= l template.created_at.to_date, formats: :short %>
    <%= _('Last updated') %><%= l template.updated_at.to_date, formats: :short %>
    diff --git a/app/views/templates/admin_index.html.erb b/app/views/templates/admin_index.html.erb new file mode 100644 index 0000000..2acb25a --- /dev/null +++ b/app/views/templates/admin_index.html.erb @@ -0,0 +1,162 @@ +<%= stylesheet_link_tag "admin" %> + +

    + <%= _('Templates') %> +

    +
    +

    + <%= _('Own templates') %> +

    + +
    + <%= raw _("

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    ")%> +
    +
    + +
    + <%= link_to _('Create a template'), + admin_new_template_path, + class: 'btn btn-primary' %> +
    +
    +
    + + +<% if @org_templates.length > 0 then %> + + + + + + + + + + + + <% @org_templates.each do |hash| %> + + + + + + + + + + <% end %> + +
    <%= _('Title') %><%= _('Description') %><%= _('Status') %><%= _('Last updated') %><%= _('Actions') %>
    + <%= hash[:current].title %> + + <%= raw hash[:current].description.truncate(90, omission: _('... (continued)')) unless hash[:current].description.nil? %> + + <% if hash[:live].nil? %> + <%= _('Unpublished') %> + + <% elsif hash[:current].dirty? %> + <%= _('Unpublished changes') %> + + <% else %> + <%= _('Published') %> + <% end %> + + <% last_temp_updated = hash[:current].updated_at %> + <%= l last_temp_updated.to_date, formats: :short %> + + <%= link_to _('Edit'), admin_template_template_path(id: hash[:current].id, edit: "true"), class: "dmp_table_link" %> + <%= link_to _('History'), admin_template_history_template_path(id: hash[:current].id), class: "dmp_table_link" %> + + <% if hash[:live].nil? %> +
    <%= link_to _('Publish'), admin_publish_template_path(hash[:current]), method: :put, class: "dmp_table_link" %> + <% elsif hash[:current].dirty? %> +
    <%= link_to _('Publish changes'), admin_publish_template_path(hash[:current]), method: :put, class: "dmp_table_link" %> + <% else %> +
    <%= link_to _('Unpublish'), admin_unpublish_template_path(hash[:current]), method: :put, class: "dmp_table_link" %> + <% end %> +
    + +<% end %> + +
    +
    + + +<% if !current_user.org.funder? then %> +

    + <%= _('Funders templates') %> +

    + + + <% if @funder_templates.length > 0 then %> + + + + + + + + + + + + <% @funder_templates.each do |hash| %> + + + + + + + + <% end %> + +
    <%= _('Title') %><%= _('Description') %><%= _('Status') %><%= _('Last updated') %><%= _('Actions') %>
    + <%= hash[:current].title%> + + <%= raw hash[:current].description.truncate(90, omission: _('... (continued)')) %> + + + <% if hash[:current].customization_of.nil? %> + + <% else %> + + <% if hash[:stale] %> + <%= _('Original funder template has changed!')%> + <% elsif hash[:live].nil? %> + + <%= b_label = _('Un-published') %> + <% elsif !hash[:current].published? %> + <%= _('You have un-published changes') %> + <% else %> + <%= _('Published') %> + <% end %> + <% end %> + + <% last_updated = hash[:current].updated_at %> + <%= l last_updated.to_date, formats: :short %> + + <% if hash[:current].customization_of.nil? %> + <% b_label = _('Customise') %> + <%= link_to b_label, admin_customize_template_path(hash[:current]), method: :get, class: "dmp_table_link" %> + <% else %> + <% if hash[:stale] %> + <% b_label = _('Transfer customisation') %> + <%= link_to b_label, admin_transfer_customization_template_path(hash[:funder_live]), class: "dmp_table_link" %> + <% else %> + <% b_label = _('Edit customisation') %> + <%= link_to b_label, admin_template_template_path(hash[:current]), class: "dmp_table_link" %> + <% end %> + + <% end %> + + <% if !hash[:current].customization_of.nil? %> + <% if hash[:live].nil? || hash[:current].dirty? %> + <%= link_to _('Publish'), admin_publish_template_path(hash[:current]), method: :put, class: "dmp_table_link" %> + <% end %> + <% if !hash[:live].nil? %> + <%= link_to _('Unpublish'), admin_unpublish_template_path(hash[:current]), method: :put, class: "dmp_table_link" %> + <% end %> + <% end %> +
    + <% end %> +<% end %> diff --git a/app/views/templates/admin_new.html.erb b/app/views/templates/admin_new.html.erb new file mode 100644 index 0000000..bfdf195 --- /dev/null +++ b/app/views/templates/admin_new.html.erb @@ -0,0 +1,48 @@ +<%= stylesheet_link_tag "admin" %> +<% javascript "admin.js" %> + +

    + <%= _('New template') %> + +
    + <%= link_to _('View all templates'), + admin_index_template_path, class: "btn btn-primary" %> +
    +

    + +
    +
    + +
    + <%= raw _('

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    ')%> +
    + <%= form_for :template, url: {action: "admin_create"} do |f| %> + + + + + + + + + + +
    <%= _('Title') %><%= f.text_field :title, as: :string, + class: "text_field has-tooltip", "data-toggle" => "tooltip", title: _('Please enter a title for your template.') %>
    <%= _('Description') %> +
    + <%= text_area_tag("template-desc", "", class: "tinymce") %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "template_desc_popover", rel: "popover", "data-html" => "true", "data-content" => _("
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    "))%> +
    +
    + +
    + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Cancel'), admin_index_template_path, class: "btn cancel" %> +
    +
    + <% end %> +
    +
    +<%= tinymce :content_css => asset_path('application.css') %> \ No newline at end of file diff --git a/app/views/templates/admin_template.html.erb b/app/views/templates/admin_template.html.erb new file mode 100644 index 0000000..75564de --- /dev/null +++ b/app/views/templates/admin_template.html.erb @@ -0,0 +1,62 @@ +<%= stylesheet_link_tag "admin" %> +<% javascript 'admin.js' %> + +

    + <%= @template.title %> + +
    + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
    +

    + +
    + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @template, hash: @hash, active: "show_template"} %> + + +
    +
    + <% if @template == @current && @template.customization_of.nil? %> + + <% end %> +
    + <%= render partial: "templates/show_template", locals: {template: @template, current: @current, hash: @hash}%> +
    +
    + + <% if @hash[:template][:phases].present? %> + <% if @hash[:template][:phases].length == 1 %> + <% @hash[:template][:phases].each do |phase_no, phase| %> + + <%= render partial: 'templates/show_phases_sections', locals: {phase: phase[:data], phase_hash: phase, template: @template, current: @current} %> + <% end %> + <% else %> + <% (1..@hash[:template][:phases].length).each do |phase_no| %> + <% phase = @hash[:template][:phases][phase_no] %> +
    +
    + +
    +
    + + <%= render partial: 'templates/show_phases_sections', locals: {phase: phase[:data], phase_hash: phase, template: @template, current: @current}%> +
    +
    +
    +
    + <% end %> + <% end %> + <% end %> +
    + +<%= tinymce :content_css => asset_path('application.css') %> diff --git a/app/views/templates/admin_template_history.html.erb b/app/views/templates/admin_template_history.html.erb new file mode 100644 index 0000000..95897a8 --- /dev/null +++ b/app/views/templates/admin_template_history.html.erb @@ -0,0 +1,66 @@ +<%= stylesheet_link_tag "admin" %> + +

    + <%= @template.title %> +

    +
    +

    + <%= _('Template History') %> +

    + +
    + <%= raw _('

    Here you can view previously published versions of your template. These can no longer be modified.

    ')%> +
    +
    + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
    + +
    + + +<% if @templates.length > 0 then %> + + + + + + + + + + + + <% @templates.each do |org_template| %> + + + + + + + + <%end%> + +
    <%= _('Title') %><%= _('Version') %> <%= _('Published') %><%= _('Last updated') %><%= _('Actions') %>
    + <%= org_template.title%> + <% if org_template == @current && !org_template.published%> +     <%=_('Draft')%> + <% end %> + + <%= org_template.version %> + + <%= (org_template.published? ? _('Yes') : _('No')) %> + + <% last_temp_updated = org_template.updated_at %> + <% org_template.phases.each do |phase|%> + <% if org_template.updated_at.to_date < phase.updated_at.to_date %> + <% last_temp_updated = phase.updated_at %> + <% end %> + <% end %> + <%= l last_temp_updated.to_date, formats: :short %> + + <%= link_to (org_template == @current ? _('Edit') : _('View')), admin_template_template_path(id: org_template), class: "dmp_table_link"%> +
    + +<%end%> diff --git a/app/views/templates/export.pdf.erb b/app/views/templates/export.pdf.erb new file mode 100644 index 0000000..3726b39 --- /dev/null +++ b/app/views/templates/export.pdf.erb @@ -0,0 +1,23 @@ + + + + + + <%= @template.title %> + + + + +

    <%= @template.title %>

    + + \ No newline at end of file diff --git a/app/views/user_mailer/api_token_granted_notification.html.erb b/app/views/user_mailer/api_token_granted_notification.html.erb index e72d6f2..69051d0 100644 --- a/app/views/user_mailer/api_token_granted_notification.html.erb +++ b/app/views/user_mailer/api_token_granted_notification.html.erb @@ -1,6 +1,12 @@ -

    <% t('custom_devise.hello') %><%= @user.name %>

    - - -

    -<% t('helpers.api_granted') %>"<%= link_to t('helpers.api_view_token'), controller: "users", action: "edit") %>". -

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <% _('Hello ') %><%= @user.name %>

    + +

    <%= _('You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found ')%>here. +

    + +

    + <%=_('All the best,')%> +
    + <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>. +

    +<% end %> \ No newline at end of file diff --git a/app/views/user_mailer/permissions_change_notification.html.erb b/app/views/user_mailer/permissions_change_notification.html.erb index 10e3c8a..c2c0740 100644 --- a/app/views/user_mailer/permissions_change_notification.html.erb +++ b/app/views/user_mailer/permissions_change_notification.html.erb @@ -1,12 +1,18 @@ -

    <%= t('custom_devise.hello') %> <%= @project_group.user.name %>

    - +<% FastGettext.with_locale FastGettext.default_locale do %> <% -access_level = "read-only" -if @project_group.access_level == 2 then - access_level = "editor" -elsif @project_group.access_level == 3 then - access_level = "co-owner" -end + access_level = "read-only" + permissions = "This means you can read the plan and leave comments." + if @role.editor? + access_level = "editor" + permissions = "This means you can write and edit the plan in a collaborative manner." + end + if @role.administrator? + access_level = "co-owner" + permissions = "This means you can write and edit the plan in a collaborative manner. You can also grant rights to other collaborators." + end %> +

    <%= _('Hello ') %><%= @role.user.name %>,

    +

    <%= _('Your permissions relating to ') %> "<%= link_to @role.plan.title, url_for(action: 'show', controller: 'plans', id: @role.plan.id, locale: FastGettext.default_locale) %>" <%= _(' have been changed by') %><%="#{@current_user.name(false)}. " %><%= _('You now have ') %><%= access_level %><%= _(' access. ') %><%= permissions %>

    +

    <%=_('All the best,')%>
    <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>.

    -

    <%= t('helpers.mailer.permission_relating') %>"<%= link_to @project_group.project.title, url_for(action: 'show', controller: 'projects', id: @project_group.project.id, locale: I18n.default_locale) %>"<%= t('helpers.mailer.changed') %><%= access_level %> <%= t('helpers.mailer.access') %>

    +<% end %> diff --git a/app/views/user_mailer/project_access_removed_notification.html.erb b/app/views/user_mailer/project_access_removed_notification.html.erb index 79f8d29..53a5e40 100644 --- a/app/views/user_mailer/project_access_removed_notification.html.erb +++ b/app/views/user_mailer/project_access_removed_notification.html.erb @@ -1,3 +1,6 @@ -

    <%= t('custom_devise.hello') %><%= @user.name %>

    +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _('Hello ') %><%= @user.email %>,

    +

    <%= _('Your access to ') %>"<%= @plan.title %>"<%= _(' has been removed by ') %><%= "#{@current_user.name(false)}"%>.

    +

    <%=_('All the best,')%>
    <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>.

    -

    <%= t('helpers.mailer.access_to') %>"<%= @project.title %>"<%= t('helpers.mailer.removed') %>

    +<% end %> diff --git a/app/views/user_mailer/sharing_notification.html.erb b/app/views/user_mailer/sharing_notification.html.erb index f93548b..dc2fed4 100644 --- a/app/views/user_mailer/sharing_notification.html.erb +++ b/app/views/user_mailer/sharing_notification.html.erb @@ -1,13 +1,22 @@ -

    <%= t('custom_devise.hello') %> <%= @project_group.user.name %>

    - +<% FastGettext.with_locale FastGettext.default_locale do %> <% -access_level = "read-only" -if @project_group.access_level == 2 then - access_level = "editor" -elsif @project_group.access_level == 3 then - access_level = "co-owner" -end + access_level = "read-only" + permissions = "This means you can read the plan and leave comments." + if @role.editor? + access_level = "editor" + permissions = "This means you can write and edit the plan in a collaborative manner." + end + if @role.administrator? + access_level = "co-owner" + permissions = "This means you can write and edit the plan in a collaborative manner. You can also grant rights to other collaborators." + end %> +

    <%= _('Hello ') %><%= @role.user.name %>,

    +

    <%= _('A colleague has invited you to contribute to their Data Management Plan at ') %><%= link_to Rails.configuration.branding[:application][:name], root_url %>.

    +

    <%= _('You have been given ') %><%= access_level %><%= _(' access to') %> "<%= link_to @role.plan.title, url_for(action: 'show', controller: 'plans', id: @role.plan.id, locale: FastGettext.default_locale) %>" <%=_('by ')%><%= "#{@user.name(false)}" %>.

    +

    <%= link_to _('Click here'), url_for(action: 'show', controller: 'plans', id: @role.plan.id, locale: FastGettext.default_locale) %><%= _(' to accept the invitation, (or copy ') %><%= url_for(action: 'show', controller: 'plans', id: @role.plan.id, locale: FastGettext.default_locale) %><%= _(' into your browser)')%>

    +

    <%= _('If you don\'t want to accept the invitation, please ignore this email.') %>

    +

    <%=_('All the best,')%>
    <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>.

    -

    <%= t('helpers.mailer.given') %><%= access_level %><%= t('helpers.mailer.access_two') %><%= link_to @project_group.project.title, url_for(action: 'show', controller: 'projects', id: @project_group.project.id, locale: I18n.default_locale) %>".

    +<% end %> diff --git a/app/views/user_mailer/welcome_notification.html.erb b/app/views/user_mailer/welcome_notification.html.erb new file mode 100644 index 0000000..7bda2d0 --- /dev/null +++ b/app/views/user_mailer/welcome_notification.html.erb @@ -0,0 +1,11 @@ +<% FastGettext.with_locale FastGettext.default_locale do %> +

    <%= _('Welcome to ') %><%= Rails.configuration.branding[:application][:name] %>

    + +

    <%= Rails.configuration.branding[:application][:name] %><%= _(' will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on ') %><%= Rails.configuration.branding[:application][:email] %>

    + +

    + <%=_('All the best,')%> +
    + <%= _('The ')%><%= Rails.configuration.branding[:application][:name] %><%=_(' team')%>. +

    +<% end %> \ No newline at end of file diff --git a/app/views/users/admin_api_update.html.erb b/app/views/users/admin_api_update.html.erb deleted file mode 100644 index 3f26ec2..0000000 --- a/app/views/users/admin_api_update.html.erb +++ /dev/null @@ -1,60 +0,0 @@ -<%= stylesheet_link_tag "admin" %> - -

    - <%= t('org_admin.users_list') %> -

    - -<%= raw t('org_admin.user_text_html')%> -<% @users = current_user.organisation.users %> - - - - - - - - - <% if current_user.organisation.token_permission_types.count > 0 %> - - <% end %> - - - - - <%= form_tag( admin_api_update_users_path, method: :put) do %> - <% @users.each do |user| %> - <% if !user.nil? then%> - - - - - - - <% if current_user.organisation.token_permission_types.count > 0 %> - - <% end %> - - <% end %> - <% end %> - - <%= submit_tag "Update Users" %> - <% end %> -
    <%= t('org_admin.user_full_name') %><%= t('org_admin.user_name') %><%= t('org_admin.last_logged_in') %><%= t('org_admin.how_many_plans') %><%= t('org_admin.is_org_admin') %><%= t('org_admin.api_privleges') %>
    - <% if !user.name.nil? then%> - <%= user.name %> - <% end %> - - <%= user.email %> - - <% if !user.last_sign_in_at.nil? then%> - <%= l user.last_sign_in_at.to_date, :formats => :short %> - <% end %> - - <% if !user.project_groups.nil? then%> - <%= user.project_groups.count %> - <% end %> - - <%= check_box_tag "org_admin_ids[]", user.id, user.is_org_admin? %> - - <%= check_box_tag "api_user_ids[]", user.id, user.api_token !="" %> -
    \ No newline at end of file diff --git a/app/views/users/admin_grant_permissions.html.erb b/app/views/users/admin_grant_permissions.html.erb index ca5a170..e15b781 100644 --- a/app/views/users/admin_grant_permissions.html.erb +++ b/app/views/users/admin_grant_permissions.html.erb @@ -1,29 +1,54 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t('org_admin.edit_user_privileges') %> + <%= _('Edit User Privileges') %>

    <%= form_tag( admin_update_permissions_user_path(@user), method: :put) do %> - +
    - - <% @roles.each do |role| %> - + + <% @perms.each do |perm| %> + <% case perm.name when 'grant_permissions' %> + + <% when 'modify_templates' %> + + <% when 'modify_guidance' %> + + <% when 'use_api' %> + + <% when 'change_org_details' %> + + <% end %> <% end %> - <% @roles.each do |role| %> + <% @perms.each do |perm| %> <% end %>
    <%= role.name %>
    + <%= _('Grant permissions') %> + + <%= _('Modify templates') %> + + <%= _('Modify guidance') %> + + <%= _('API rights') %> + + <%= _('Change organisation details') %> +
    - <%= check_box_tag "role_ids[]", role.id, @user.roles.include?(role) %> + <%= check_box_tag "perm_ids[]", perm.id, @user.perms.include?(perm) %>
    - <%= submit_tag t('helpers.submit.save') %> + <%= submit_tag _('Save') %> <% end %> -
    \ No newline at end of file +
    diff --git a/app/views/users/admin_index.html.erb b/app/views/users/admin_index.html.erb index c914f49..5a8a19c 100644 --- a/app/views/users/admin_index.html.erb +++ b/app/views/users/admin_index.html.erb @@ -1,18 +1,18 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t('org_admin.users_list') %> + <%= _('List of users') %>

    -<%= raw t('org_admin.user_text_html')%> +<%= raw _('Below is a list of users registered for your organisation. You can sort the data by each field.')%> - - - - - + + + + + @@ -33,13 +33,13 @@ <% end %> diff --git a/config/application.rb b/config/application.rb index f13810f..96f8c18 100644 --- a/config/application.rb +++ b/config/application.rb @@ -68,15 +68,26 @@ config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif *ico) config.assets.precompile += %w(*mp4 *webm *ogg *ogv *swf) - config.assets.precompile += %w(plans.js) - config.assets.precompile += %w(projects.js) + config.assets.precompile += %w(plans.js) config.assets.precompile += %w(jquery.placeholder.js) config.assets.precompile += %w(jquery.tablesorter.js) + config.assets.precompile += %w(jquery-accessible-autocomplet-list-aria.js) config.assets.precompile += %w(export_configure.js) config.assets.precompile += %w(toolbar.js) config.assets.precompile += %w(admin.js) config.assets.precompile += %w(admin.css) + config.assets.precompile += %w(roadmap-form.scss) + config.assets.precompile += %w(plans/new_plan.js) + config.assets.precompile += %w(plans/edit.js) + config.assets.precompile += %w(plans/share.js) + config.assets.precompile += %w(contacts/new_contact.js) + config.assets.precompile += %w(shared/register_form.js) + config.assets.precompile += %w(answers/status.js) + config.assets.precompile += %w(notes/index.js) + config.assets.precompile += %w(bootstrap_listeners.js) + config.assets.precompile += %w(Dmproadmap.js) + config.autoload_paths += %W(#{config.root}/lib) config.action_controller.include_all_helpers = true @@ -85,12 +96,12 @@ # Enable shibboleth as an alternative authentication method # Requires server configuration and omniauth shibboleth provider configuration - # See config/initializers/omniauth.rb - config.shibboleth_enabled = false + # See config/initializers/devise.rb + config.shibboleth_enabled = true - # Absolute path to Shibboleth SSO Login - #config.shibboleth_login = 'https://localhost/Shibboleth.sso/Login' - + # Relative path to Shibboleth SSO Logout + config.shibboleth_logout_url = '/Shibboleth.sso/Logout?return=' + # Active Record will no longer suppress errors raised in after_rollback or after_commit # in the next version. Devise appears to be using those callbacks. # To accept the new behaviour use 'true' otherwise use 'false' @@ -98,6 +109,5 @@ # Load Branded terminology (e.g. organization name, application name, etc.) config.branding = config_for(:branding).deep_symbolize_keys - end end diff --git a/config/base_site.html b/config/base_site.html new file mode 100644 index 0000000..e20fabe --- /dev/null +++ b/config/base_site.html @@ -0,0 +1,28 @@ + + + + + + + + Bootstrap 101 Template + + + + + + + + + +

    Hello, world!

    + + + + + + + \ No newline at end of file diff --git a/config/branding.yml b/config/branding.yml deleted file mode 100644 index 578347c..0000000 --- a/config/branding.yml +++ /dev/null @@ -1,29 +0,0 @@ -defaults: &defaults - legal_entity: 'the University of Edinburgh, University of Glasgow and the University of California' - - organisation: - name: 'Digital Curation Center and University of California Curation Center' - abbreviation: 'DCC and UC3' - url: 'https://github.com/DMPRoadmap/roadmap/wiki' - copywrite_name: 'DCC and UC3' - email: 'dmponline@dcc.ac.uk' - - application: - name: 'DMPRoadmap' - url: 'https://github.com/DMPRoadmap/roadmap' - version: '0.1.0' - release_notes_url: 'https://github.com/DMPRoadmap/roadmap/wiki/Releases' - issue_list_url: 'https://github.com/DMPRoadmap/roadmap/issues' - user_group_subscription_url: 'http://listserv.ucop.edu/cgi-bin/wa.exe?SUBED1=ROADMAP-L&A=1' - -development: - <<: *defaults - -test: - <<: *defaults - -staging: - <<: *defaults - -production: - <<: *defaults \ No newline at end of file diff --git a/config/branding_example.yml b/config/branding_example.yml new file mode 100644 index 0000000..329fa1d --- /dev/null +++ b/config/branding_example.yml @@ -0,0 +1,30 @@ +defaults: &defaults + legal_entity: 'the University of Edinburgh, University of Glasgow and the University of California' + + # Warning: The abbreviation here should match the org.abbreviation value registered in your database! + organisation: + name: 'Curation Center' + abbreviation: 'CC' + url: 'https://github.com/DMPRoadmap/roadmap/wiki' + copywrite_name: 'Curation Centre (CC)' + email: 'tester@cc_curation_centre.org' + + application: + name: 'DMPRoadmap' + url: 'https://github.com/DMPRoadmap/roadmap' + version: '0.1.0' + release_notes_url: 'https://github.com/DMPRoadmap/roadmap/wiki/Releases' + issue_list_url: 'https://github.com/DMPRoadmap/roadmap/issues' + user_group_subscription_url: 'http://listserv.ucop.edu/cgi-bin/wa.exe?SUBED1=ROADMAP-L&A=1' + +development: + <<: *defaults + +test: + <<: *defaults + +stage: + <<: *defaults + +production: + <<: *defaults diff --git a/config/environment.rb b/config/environment.rb index c82b616..3488440 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -5,5 +5,4 @@ Rails.logger = Logger.new(STDOUT) # Initialize the Rails application. -#DMPonline4::Application.initialize! Rails.application.initialize! \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 0978811..d7fd24b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -37,6 +37,8 @@ # Log error messages when you accidentally call methods on nil. config.whiny_nils = true + config.log_level = :debug + # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin @@ -48,4 +50,10 @@ config.action_mailer.perform_deliveries = false BetterErrors::Midleware.allow_ip! "10.0.2.2" if defined?(BetterErrors) && Rails.env == :development + + config.after_initialize do + ActiveRecord::Base.logger = Rails.logger.clone + ActiveRecord::Base.logger.level = Logger::INFO + ActiveRecord::Base.logger.level = Logger::DEBUG + end end diff --git a/config/environments/production.rb b/config/environments/production.rb index 1128592..76a2c35 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -64,6 +64,9 @@ # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false + # Set default host for mailer URLs + # config.action_mailer.default_url_options = {host: "example.com"} + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb deleted file mode 100644 index 2e1c9c6..0000000 --- a/config/initializers/active_admin.rb +++ /dev/null @@ -1,274 +0,0 @@ -ActiveAdmin.setup do |config| - # == Site Title - # - # Set the title that is displayed on the main layout - # for each of the active admin pages. - # - config.site_title = "DMPRoadmap" - - # Set the link url for the title. For example, to take - # users to your main site. Defaults to no link. - # - config.site_title_link = "/" - - # Set an optional image to be displayed for the header - # instead of a string (overrides :site_title) - # - # Note: Aim for an image that's 21px high so it fits in the header. - # - # config.site_title_image = "logo.png" - - # == Default Namespace - # - # Set the default namespace each administration resource - # will be added to. - # - # eg: - # config.default_namespace = :hello_world - # - # This will create resources in the HelloWorld module and - # will namespace routes to /hello_world/* - # - # To set no namespace by default, use: - # config.default_namespace = false - # - # Default: - # config.default_namespace = :admin - # - # You can customize the settings for each namespace by using - # a namespace block. For example, to change the site title - # within a namespace: - # - # config.namespace :admin do |admin| - # admin.site_title = "Custom Admin Title" - # end - # - # This will ONLY change the title for the admin section. Other - # namespaces will continue to use the main "site_title" configuration. - - # == User Authentication - # - # Active Admin will automatically call an authentication - # method in a before filter of all controller actions to - # ensure that there is a currently logged in admin user. - # - # This setting changes the method which Active Admin calls - # within the application controller. - # config.authentication_method = :authenticate_admin_user! - config.authentication_method = :authenticate_admin! - - # == User Authorization - # - # Active Admin will automatically call an authorization - # method in a before filter of all controller actions to - # ensure that there is a user with proper rights. You can use - # CanCanAdapter or make your own. Please refer to documentation. - # config.authorization_adapter = ActiveAdmin::CanCanAdapter - - # In case you prefer Pundit over other solutions you can here pass - # the name of default policy class. This policy will be used in every - # case when Pundit is unable to find suitable policy. - # config.pundit_default_policy = "MyDefaultPunditPolicy" - - # You can customize your CanCan Ability class name here. - # config.cancan_ability_class = "Ability" - - # You can specify a method to be called on unauthorized access. - # This is necessary in order to prevent a redirect loop which happens - # because, by default, user gets redirected to Dashboard. If user - # doesn't have access to Dashboard, he'll end up in a redirect loop. - # Method provided here should be defined in application_controller.rb. - # config.on_unauthorized_access = :access_denied - - # == Current User - # - # Active Admin will associate actions with the current - # user performing them. - # - # This setting changes the method which Active Admin calls - # (within the application controller) to return the currently logged in user. - # config.current_user_method = :current_admin_user - config.current_user_method = :current_user - - # == Logging Out - # - # Active Admin displays a logout link on each screen. These - # settings configure the location and method used for the link. - # - # This setting changes the path where the link points to. If it's - # a string, the strings is used as the path. If it's a Symbol, we - # will call the method to return the path. - # - # Default: - config.logout_link_path = :destroy_user_session_path - - # This setting changes the http method used when rendering the - # link. For example :get, :delete, :put, etc.. - # - # Default: - # config.logout_link_method = :get - - # == Root - # - # Set the action to call for the root path. You can set different - # roots for each namespace. - # - # Default: - # config.root_to = 'dashboard#index' - - # == Admin Comments - # - # This allows your users to comment on any resource registered with Active Admin. - # - # You can completely disable comments: - # config.comments = false - # - # You can change the name under which comments are registered: - # config.comments_registration_name = 'AdminComment' - # - # You can change the order for the comments and you can change the column - # to be used for ordering: - # config.comments_order = 'created_at ASC' - # - # You can disable the menu item for the comments index page: - config.comments_menu = false - # - # You can customize the comment menu: - # config.comments_menu = { parent: 'Admin', priority: 1 } - - # == Batch Actions - # - # Enable and disable Batch Actions - # - config.batch_actions = true - - # == Controller Filters - # - # You can add before, after and around filters to all of your - # Active Admin resources and pages from here. - # - # config.before_filter :do_something_awesome - - # == Localize Date/Time Format - # - # Set the localize format to display dates and times. - # To understand how to localize your app with I18n, read more at - # https://github.com/svenfuchs/i18n/blob/master/lib%2Fi18n%2Fbackend%2Fbase.rb#L52 - # - config.localize_format = :long - - # == Setting a Favicon - # - # config.favicon = 'favicon.ico' - - # == Meta Tags - # - # Add additional meta tags to the head element of active admin pages. - # - # Add tags to all pages logged in users see: - # config.meta_tags = { author: 'My Company' } - - # By default, sign up/sign in/recover password pages are excluded - # from showing up in search engine results by adding a robots meta - # tag. You can reset the hash of meta tags included in logged out - # pages: - # config.meta_tags_for_logged_out_pages = {} - - # == Removing Breadcrumbs - # - # Breadcrumbs are enabled by default. You can customize them for individual - # resources or you can disable them globally from here. - # - # config.breadcrumb = false - - # == Register Stylesheets & Javascripts - # - # We recommend using the built in Active Admin layout and loading - # up your own stylesheets / javascripts to customize the look - # and feel. - # - # To load a stylesheet: - # config.register_stylesheet 'my_stylesheet.css' - # - # You can provide an options hash for more control, which is passed along to stylesheet_link_tag(): - # config.register_stylesheet 'my_print_stylesheet.css', media: :print - # - # To load a javascript file: - # config.register_javascript 'my_javascript.js' - - # == CSV options - # - # Set the CSV builder separator - # config.csv_options = { col_sep: ';' } - # - # Force the use of quotes - # config.csv_options = { force_quotes: true } - - # == Menu System - # - # You can add a navigation menu to be used in your application, or configure a provided menu - # - # To change the default utility navigation to show a link to your website & a logout btn - # - # config.namespace :admin do |admin| - # admin.build_menu :utility_navigation do |menu| - # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } - # admin.add_logout_button_to_menu menu - # end - # end - # - # If you wanted to add a static menu item to the default menu provided: - # - # config.namespace :admin do |admin| - # admin.build_menu :default do |menu| - # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } - # end - # end - - # == Download Links - # - # You can disable download links on resource listing pages, - # or customize the formats shown per namespace/globally - # - # To disable/customize for the :admin namespace: - # - # config.namespace :admin do |admin| - # - # # Disable the links entirely - # admin.download_links = false - # - # # Only show XML & PDF options - # admin.download_links = [:xml, :pdf] - # - # # Enable/disable the links based on block - # # (for example, with cancan) - # admin.download_links = proc { can?(:view_download_links) } - # - # end - - # == Pagination - # - # Pagination is enabled by default for all resources. - # You can control the default per page count for all resources here. - # - # config.default_per_page = 30 - # - # You can control the max per page count too. - # - # config.max_per_page = 10_000 - - # == Filters - # - # By default the index screen includes a "Filters" sidebar on the right - # hand side with a filter for each attribute of the registered model. - # You can enable or disable them for all resources here. - # - # config.filters = true - # - # By default the filters include associations in a select, which means - # that every record will be loaded for each association. - # You can enabled or disable the inclusion - # of those filters by default here. - # - # config.include_default_association_filters = true -end \ No newline at end of file diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb new file mode 100644 index 0000000..927a84f --- /dev/null +++ b/config/initializers/constants.rb @@ -0,0 +1,2 @@ +LANGUAGES = (ActiveRecord::Base.connection.table_exists? 'languages') ? Language.sorted_by_abbreviation : [] +MANY_LANGUAGES = LANGUAGES.length > 1 diff --git a/config/initializers/contac_us_example.rb b/config/initializers/contac_us_example.rb deleted file mode 100644 index 0d3b4f6..0000000 --- a/config/initializers/contac_us_example.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Use this hook to configure contact mailer. -ContactUs.setup do |config| - - # ==> Mailer Configuration - - # Configure the e-mail address which email notifications should be sent from. If emails must be sent from a verified email address you may set it here. - # Example: - # config.mailer_from = "contact@please-change-me.com" - config.mailer_from = nil - - # Configure the e-mail address which should receive the contact form email notifications. - config.mailer_to = "example@email.address" - - # ==> Form Configuration - - # Configure the form to ask for the users name. - config.require_name = true - - # Configure the form to ask for a subject. - config.require_subject = true - - # Configure the form gem to use. - # Example: - # config.form_gem = 'formtastic - # config.form_gem = 'formtastic' - -end diff --git a/config/initializers/contact_us.rb.example b/config/initializers/contact_us.rb.example new file mode 100644 index 0000000..0d3b4f6 --- /dev/null +++ b/config/initializers/contact_us.rb.example @@ -0,0 +1,27 @@ +# Use this hook to configure contact mailer. +ContactUs.setup do |config| + + # ==> Mailer Configuration + + # Configure the e-mail address which email notifications should be sent from. If emails must be sent from a verified email address you may set it here. + # Example: + # config.mailer_from = "contact@please-change-me.com" + config.mailer_from = nil + + # Configure the e-mail address which should receive the contact form email notifications. + config.mailer_to = "example@email.address" + + # ==> Form Configuration + + # Configure the form to ask for the users name. + config.require_name = true + + # Configure the form to ask for a subject. + config.require_subject = true + + # Configure the form gem to use. + # Example: + # config.form_gem = 'formtastic + # config.form_gem = 'formtastic' + +end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb deleted file mode 100644 index f31db11..0000000 --- a/config/initializers/devise.rb +++ /dev/null @@ -1,272 +0,0 @@ -require "custom_failure" - -# Use this hook to configure devise mailer, warden hooks and so forth. -# Many of these configuration options can be set straight in your model. -Devise.setup do |config| - # The secret key used by Devise. Devise uses this key to generate - # random tokens. Changing this key will render invalid all existing - # confirmation, reset password and unlock tokens in the database. - # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key` - # by default. You can change it below and use your own secret key. - # config.secret_key = '65991d837d53ee81812e8c15598e3f691d03d5517d9e0073b6f6eab94df0e8a8c3d6a8bc3c11f1972520187f233bf5e355645a0c7224108ed2a578e45af759cd' - - # ==> Mailer Configuration - # Configure the e-mail address which will be shown in Devise::Mailer, - # note that it will be overwritten if you use your own mailer class - # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' - - # Configure the class responsible to send e-mails. - # config.mailer = 'Devise::Mailer' - - # ==> ORM configuration - # Load and configure the ORM. Supports :active_record (default) and - # :mongoid (bson_ext recommended) by default. Other ORMs may be - # available as additional gems. - require 'devise/orm/active_record' - - # ==> Configuration for any authentication mechanism - # Configure which keys are used when authenticating a user. The default is - # just :email. You can configure it to use [:username, :subdomain], so for - # authenticating a user, both parameters are required. Remember that those - # parameters are used only when authenticating and not when retrieving from - # session. If you need permissions, you should implement that in a before filter. - # You can also supply a hash where the value is a boolean determining whether - # or not authentication should be aborted when the value is not present. - # config.authentication_keys = [:email] - - # Configure parameters from the request object used for authentication. Each entry - # given should be a request method and it will automatically be passed to the - # find_for_authentication method and considered in your model lookup. For instance, - # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. - # The same considerations mentioned for authentication_keys also apply to request_keys. - # config.request_keys = [] - - # Configure which authentication keys should be case-insensitive. - # These keys will be downcased upon creating or modifying a user and when used - # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [:email] - - # Configure which authentication keys should have whitespace stripped. - # These keys will have whitespace before and after removed upon creating or - # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [:email] - - # Tell if authentication through request.params is enabled. True by default. - # It can be set to an array that will enable params authentication only for the - # given strategies, for example, `config.params_authenticatable = [:database]` will - # enable it only for database (email + password) authentication. - # config.params_authenticatable = true - - # Tell if authentication through HTTP Auth is enabled. False by default. - # It can be set to an array that will enable http authentication only for the - # given strategies, for example, `config.http_authenticatable = [:database]` will - # enable it only for database authentication. The supported strategies are: - # :database = Support basic authentication with authentication key + password - # config.http_authenticatable = false - - # If 401 status code should be returned for AJAX requests. True by default. - # config.http_authenticatable_on_xhr = true - - # The realm used in Http Basic Authentication. 'Application' by default. - # config.http_authentication_realm = 'Application' - - # It will change confirmation, password recovery and other workflows - # to behave the same regardless if the e-mail provided was right or wrong. - # Does not affect registerable. - # config.paranoid = true - - # By default Devise will store the user in session. You can skip storage for - # particular strategies by setting this option. - # Notice that if you are skipping storage for all authentication paths, you - # may want to disable generating routes to Devise's sessions controller by - # passing skip: :sessions to `devise_for` in your config/routes.rb - config.skip_session_storage = [:http_auth] - - # By default, Devise cleans up the CSRF token on authentication to - # avoid CSRF token fixation attacks. This means that, when using AJAX - # requests for sign in and sign up, you need to get a new CSRF token - # from the server. You can disable this option at your own risk. - # config.clean_up_csrf_token_on_authentication = true - - # ==> Configuration for :database_authenticatable - # For bcrypt, this is the cost for hashing the password and defaults to 10. If - # using other encryptors, it sets how many times you want the password re-encrypted. - # - # Limiting the stretches to just one in testing will increase the performance of - # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use - # a value less than 10 in other environments. Note that, for bcrypt (the default - # encryptor), the cost increases exponentially with the number of stretches (e.g. - # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). - config.stretches = Rails.env.test? ? 1 : 10 - - # Setup a pepper to generate the encrypted password. - config.pepper = 'fce14df8477896bd9cc8ea3724d97270a5f19cb6544173d17b7e148cf360bf16449d96318275bfb3efde7b3b377db06cede2b64efb0a6d07dd02dd5076f639c9' - - # Send a notification email when the user's password is changed - # config.send_password_change_notification = false - - # ==> Configuration for :confirmable - # A period that the user is allowed to access the website even without - # confirming their account. For instance, if set to 2.days, the user will be - # able to access the website for two days without confirming their account, - # access will be blocked just in the third day. Default is 0.days, meaning - # the user cannot access the website without confirming their account. - # config.allow_unconfirmed_access_for = 2.days - - # A period that the user is allowed to confirm their account before their - # token becomes invalid. For example, if set to 3.days, the user can confirm - # their account within 3 days after the mail was sent, but on the fourth day - # their account can't be confirmed with the token any more. - # Default is nil, meaning there is no restriction on how long a user can take - # before confirming their account. - # config.confirm_within = 3.days - - # If true, requires any email changes to be confirmed (exactly the same way as - # initial account confirmation) to be applied. Requires additional unconfirmed_email - # db field (see migrations). Until confirmed, new email is stored in - # unconfirmed_email column, and copied to email column on successful confirmation. - config.reconfirmable = false - - # Defines which key will be used when confirming an account - # config.confirmation_keys = [:email] - - # ==> Configuration for :rememberable - # The time the user will be remembered without asking for credentials again. - # config.remember_for = 2.weeks - - # Invalidates all the remember me tokens when the user signs out. - config.expire_all_remember_me_on_sign_out = true - - # If true, extends the user's remember period when remembered via cookie. - # config.extend_remember_period = false - - # Options to be passed to the created cookie. For instance, you can set - # secure: true in order to force SSL only cookies. - # config.rememberable_options = {} - - # ==> Configuration for :validatable - # Range for password length. - config.password_length = 8..72 - - # Email regex used to validate email formats. It simply asserts that - # one (and only one) @ exists in the given string. This is mainly - # to give user feedback and not to assert the e-mail validity. - # config.email_regexp = /\A[^@]+@[^@]+\z/ - - # ==> Configuration for :timeoutable - # The time you want to timeout the user session without activity. After this - # time the user will be asked for credentials again. Default is 30 minutes. - config.timeout_in = 1.minutes - - # ==> Configuration for :lockable - # Defines which strategy will be used to lock an account. - # :failed_attempts = Locks an account after a number of failed attempts to sign in. - # :none = No lock strategy. You should handle locking by yourself. - # config.lock_strategy = :failed_attempts - - # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [:email] - - # Defines which strategy will be used to unlock an account. - # :email = Sends an unlock link to the user email - # :time = Re-enables login after a certain amount of time (see :unlock_in below) - # :both = Enables both strategies - # :none = No unlock strategy. You should handle unlocking by yourself. - # config.unlock_strategy = :both - - # Number of authentication tries before locking an account if lock_strategy - # is failed attempts. - # config.maximum_attempts = 20 - - # Time interval to unlock the account if :time is enabled as unlock_strategy. - # config.unlock_in = 1.hour - - # Warn on the last attempt before the account is locked. - # config.last_attempt_warning = true - - # ==> Configuration for :recoverable - # - # Defines which key will be used when recovering the password for an account - # config.reset_password_keys = [:email] - - # Time interval you can reset your password with a reset password key. - # Don't put a too small interval or your users won't have the time to - # change their passwords. - config.reset_password_within = 6.hours - - # When set to false, does not sign a user in automatically after their password is - # reset. Defaults to true, so a user is signed in automatically after a reset. - # config.sign_in_after_reset_password = true - - # ==> Configuration for :encryptable - # Allow you to use another encryption algorithm besides bcrypt (default). You can use - # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, - # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) - # and :restful_authentication_sha1 (then you should set stretches to 10, and copy - # REST_AUTH_SITE_KEY to pepper). - # - # Require the `devise-encryptable` gem when using anything other than bcrypt - # config.encryptor = :sha512 - - # ==> Scopes configuration - # Turn scoped views on. Before rendering "sessions/new", it will first check for - # "users/sessions/new". It's turned off by default because it's slower if you - # are using only default views. - # config.scoped_views = false - - # Configure the default scope given to Warden. By default it's the first - # devise role declared in your routes (usually :user). - # config.default_scope = :user - - # Set this configuration to false if you want /users/sign_out to sign out - # only the current scope. By default, Devise signs out all scopes. - # config.sign_out_all_scopes = true - - # ==> Navigation configuration - # Lists the formats that should be treated as navigational. Formats like - # :html, should redirect to the sign in page when the user does not have - # access, but formats like :xml or :json, should return 401. - # - # If you have any extra navigational formats, like :iphone or :mobile, you - # should add them to the navigational formats lists. - # - # The "*/*" below is required to match Internet Explorer requests. - # config.navigational_formats = ['*/*', :html] - - # The default HTTP method used to sign out a resource. Default is :delete. - config.sign_out_via = :delete - - # ==> OmniAuth - # Add a new OmniAuth provider. Check the wiki for more information on setting - # up on your models and hooks. - # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' - - # ==> Warden configuration - # If you want to use other strategies, that are not supported by Devise, or - # change the failure app, you can configure them inside the config.warden block. - # - # config.warden do |manager| - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end - - # ==> Mountable engine configurations - # When using Devise inside an engine, let's call it `MyEngine`, and this engine - # is mountable, there are some extra configurations to be taken into account. - # The following options are available, assuming the engine is mounted as: - # - # mount MyEngine, at: '/my_engine' - # - # The router that invoked `devise_for`, in the example above, would be: - # config.router_name = :my_engine - # - # When using OmniAuth, Devise cannot automatically set OmniAuth path, - # so you need to do it manually. For the users scope, it would be: - # config.omniauth_path_prefix = '/my_engine/users/auth' - - # Configure the system to redirect to the home page after a session timeout - config.warden do |manager| - manager.failure_app = CustomFailure - end -end diff --git a/config/initializers/devise.rb.example b/config/initializers/devise.rb.example index 17b481e..63aa90d 100644 --- a/config/initializers/devise.rb.example +++ b/config/initializers/devise.rb.example @@ -247,7 +247,30 @@ # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo' + + # Any entries here MUST match a corresponding entry in the identifier_schemes table as + # well as an identifier_schemes.schemes section in each locale file! + OmniAuth.config.full_host = 'https://my_service.hostname' + config.omniauth :orcid, + 'client_id', 'client_secret', + { + #member: false, + } + + config.omniauth :shibboleth, + { + #debug: true, + #uid_field: "HTTP_REMOTE_USER", + #shib_application_id_field: "HTTP_SHIB_APPLICATION_ID", + #shib_session_id_field: "HTTP_SHIB_SESSION_ID", + fields: [], + info_fields: { + #affiliation: "HTTP_AFFILIATION", + }, + extra_fields: [], + } + # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or # change the failure app, you can configure them inside the config.warden block. @@ -269,7 +292,7 @@ # # When using omniauth, Devise cannot automatically set Omniauth path, # so you need to do it manually. For the users scope, it would be: - # config.omniauth_path_prefix = "/my_engine/users/auth" + config.omniauth_path_prefix = "/users/auth" config.warden do |manager| manager.failure_app = CustomFailure diff --git a/config/initializers/fast_gettext.rb b/config/initializers/fast_gettext.rb new file mode 100644 index 0000000..4cbca7e --- /dev/null +++ b/config/initializers/fast_gettext.rb @@ -0,0 +1,18 @@ +def get_available_locales + languages = LANGUAGES # LANGUAGES is defined in config/initializers/constants.rb + locales = [] + languages.each do |l| + locales << l.abbreviation + end + return locales.empty? ? ['en_GB'] : locales +end + +def get_default_locale + language = LANGUAGES.empty? ? nil : Language.default() + return language.nil? ? 'en_GB' : language.abbreviation +end + +FastGettext.add_text_domain 'app', :path => 'config/locale', :type => :po, :ignore_fuzzy => true, :report_warning => false +FastGettext.default_text_domain = 'app' +FastGettext.default_available_locales = get_available_locales() +FastGettext.default_locale = get_default_locale() diff --git a/config/initializers/gettext_i18n_rails_js.rb b/config/initializers/gettext_i18n_rails_js.rb new file mode 100644 index 0000000..71ee9f4 --- /dev/null +++ b/config/initializers/gettext_i18n_rails_js.rb @@ -0,0 +1,10 @@ +GettextI18nRailsJs.config do |config| + config.output_path = "lib/assets/javascripts/locale" + + config.handlebars_function = "__" + config.javascript_function = "__" + + config.jed_options = { + pretty: false + } +end \ No newline at end of file diff --git a/config/initializers/locale.rb b/config/initializers/locale.rb index 1e37c81..4f18d7f 100644 --- a/config/initializers/locale.rb +++ b/config/initializers/locale.rb @@ -1,30 +1,24 @@ -module DMPonline4 - class Application < Rails::Application - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # Set the list of locales that we will support here (ie those for which we have translations for the DMPOnline application) - # tell the I18n library where to find your translations - config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] - # set default locale - # in config/initializers/locale.rb - - # set default locale to something other than :en - # initializers are run before migrations, languages table might not be present - if ActiveRecord::Base.connection.tables.include?('languages') && - ActiveRecord::Base.connection.column_exists?(:languages, :default_language) - - # If a default language is not defined in the DB use en-UK - if Language.where(default_language: true).empty? - config.i18n.default_locale = 'en-UK' - else - config.i18n.default_locale = Language.where(default_language: true).first.abbreviation - end - - else - config.i18n.default_locale = 'en-UK' # if this is not set then admin area is not working, which is required to change the default_language +# This initilializer should not be removed unless all internationalisation is handled by gettext_rails +DMPRoadmap::Application.config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] +module I18n + class Config + def locale + FastGettext.locale + end + def locale=(new_locale) + FastGettext.locale = (new_locale) + end + def default_locale + FastGettext.default_locale + end + def default_locale=(new_default_locale) + FastGettext.default_locale = (new_default_locale) + end + def available_locales + FastGettext.default_available_locales + end + def available_locales=(new_available_locales) + FastGettext.default_available_locales = (new_available_locales) + end end - - # set fallback locale - config.i18n.fallbacks = true - end end \ No newline at end of file diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb deleted file mode 100644 index ddc6ce1..0000000 --- a/config/initializers/omniauth.rb +++ /dev/null @@ -1,20 +0,0 @@ -Rails.application.config.middleware.use OmniAuth::Builder do - provider :shibboleth, { - # We're using a UK Access Management Federation IdPs here - # Shibboleth server config needs to return eppn and persistent-id attributes - # Priority given to eppn in controller if present, assuming persistent-id always populated - # Doing this the omniauth way rather than using REMOTE_USER - # See controllers/users/omniauth_callbacks_controller.rb - # Shibboleth authentication is enabled in config/application.rb - :uid_field => :"persistent-id", - :fields => [], - :extra_fields => [ - :eppn, - :affiliation, - :entitlement, - :"unscoped-affiliation", - :"targeted-id", - :mail - ], - } -end diff --git a/config/initializers/recaptcha.rb.example b/config/initializers/recaptcha.rb.example index a9e681a..0848591 100644 --- a/config/initializers/recaptcha.rb.example +++ b/config/initializers/recaptcha.rb.example @@ -1,5 +1,5 @@ Recaptcha.configure do |config| - config.public_key = 'replace_this_with_your_public_key' - config.private_key = 'replace_this_with_your_private_key' + config.site_key = 'replace_this_with_your_public_key' + config.secret_key = 'replace_this_with_your_private_key' config.proxy = 'http://someproxy.com:port' end diff --git a/config/initializers/wicked_pdf.rb.example b/config/initializers/wicked_pdf.rb.example new file mode 100644 index 0000000..1473351 --- /dev/null +++ b/config/initializers/wicked_pdf.rb.example @@ -0,0 +1,7 @@ +module DMPRoadmap + class Application < Rails::Application + WickedPdf.config = { + :exe_path => '/usr/local/bin/wkhtmltopdf' + } + end +end \ No newline at end of file diff --git a/config/initializers/wicked_pdf_example.rb b/config/initializers/wicked_pdf_example.rb deleted file mode 100644 index 103b3e5..0000000 --- a/config/initializers/wicked_pdf_example.rb +++ /dev/null @@ -1,9 +0,0 @@ -module DMPRoadmap - class Application < Rails::Application - - WickedPdf.config = { - :exe_path => '/usr/local/bin/wkhtmltopdf' - } - - end -end \ No newline at end of file diff --git a/config/locale/app.pot b/config/locale/app.pot new file mode 100644 index 0000000..30adcde --- /dev/null +++ b/config/locale/app.pot @@ -0,0 +1,1711 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-15 12:42+0000\n" +"PO-Revision-Date: 2017-06-15 12:42+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr "" + +msgid " - " +msgstr "" + +msgid " I accept the terms and conditions *" +msgstr "" + +msgid " Plan" +msgstr "" + +msgid " access to" +msgstr "" + +msgid " access. " +msgstr "" + +msgid " and " +msgstr "" + +msgid " by" +msgstr "" + +msgid " by " +msgstr "" + +msgid " has been removed by " +msgstr "" + +msgid " have been changed by" +msgstr "" + +msgid " into your browser)" +msgstr "" + +msgid " on " +msgstr "" + +msgid " or " +msgstr "" + +msgid " password. You can do this through the link below." +msgstr "" + +msgid " provided by " +msgstr "" + +msgid " team" +msgstr "" + +msgid " that has been customised by " +msgstr "" + +msgid " to accept the invitation, (or copy " +msgstr "" + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr "" + +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "" + +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "" + +msgid "%d days" +msgstr "" + +msgid "%d minutes" +msgstr "" + +msgid "%d months" +msgstr "" + +msgid "%d years" +msgstr "" + +msgid "%{application_name}" +msgstr "" + +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "" + +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "" + +msgid "%{value} is not a valid format" +msgstr "" + +msgid "(Using custom PDF formatting values)" +msgstr "" + +msgid "(Using template PDF formatting values)" +msgstr "" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "" + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "" + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "" + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "" + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "" + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "" + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "" + +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "" + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "" + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "" + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "" + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "" + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "" + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "" + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "" + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "" + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "" + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "" + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "" + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "" + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "" + +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "" + +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "" + +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "" + +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "" + +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "" + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "" + +msgid "A required setting has not been provided" +msgstr "" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "" + +msgid "Abbreviation" +msgstr "" + +msgid "About" +msgstr "" + +msgid "About %{application_name}" +msgstr "" + +msgid "Access removed" +msgstr "" + +msgid "Actions" +msgstr "" + +msgid "Add Annotations" +msgstr "" + +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "" + +msgid "Add collaborator" +msgstr "" + +msgid "Add guidance" +msgstr "" + +msgid "Add guidance group" +msgstr "" + +msgid "Add new phase +" +msgstr "" + +msgid "Add note" +msgstr "" + +msgid "Add option" +msgstr "" + +msgid "Add question" +msgstr "" + +msgid "Add section" +msgstr "" + +msgid "Additional comment area will be displayed." +msgstr "" + +msgid "Admin Details" +msgstr "" + +msgid "Admin area" +msgstr "" + +msgid "All the best," +msgstr "" + +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "" + +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "" + +msgid "Allows the user to create and edit guidance" +msgstr "" + +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +msgid "Answer" +msgstr "" + +msgid "Answer format" +msgstr "" + +msgid "Answer questions" +msgstr "" + +msgid "Answered" +msgstr "" + +msgid "Answered at" +msgstr "" + +msgid "Answered by" +msgstr "" + +msgid "Answers" +msgstr "" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "" + +msgid "Are you sure you want to remove this note?" +msgstr "" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "" + +msgid "Are you sure?" +msgstr "" + +msgid "Back" +msgstr "" + +msgid "Back to edit view" +msgstr "" + +msgid "Background" +msgstr "" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "" + +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "" + +msgid "Bottom" +msgstr "" + +msgid "By " +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "" + +msgid "Change language" +msgstr "" + +msgid "Change my password" +msgstr "" + +msgid "Change organisation details" +msgstr "" + +msgid "Check box" +msgstr "" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "" + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "" + +msgid "Click here to confirm your account" +msgstr "" + +msgid "Click the link below to unlock your account" +msgstr "" + +msgid "Co-owner" +msgstr "" + +msgid "Collaborators" +msgstr "" + +msgid "Comment" +msgstr "" + +msgid "Comment removed." +msgstr "" + +msgid "Comment was successfully created." +msgstr "" + +msgid "Comment was successfully saved." +msgstr "" + +msgid "Contact Email" +msgstr "" + +msgid "Contact Us" +msgstr "" + +msgid "Contact us" +msgstr "" + +msgid "Create a new plan" +msgstr "" + +msgid "Create a template" +msgstr "" + +msgid "Create account" +msgstr "" + +msgid "Create plan" +msgstr "" + +msgid "Created" +msgstr "" + +msgid "Created at" +msgstr "" + +msgid "Current password" +msgstr "" + +msgid "Customise" +msgstr "" + +msgid "Default" +msgstr "" + +msgid "Default answer" +msgstr "" + +msgid "Default value" +msgstr "" + +msgid "Delete" +msgstr "" + +msgid "Delete Example Answer" +msgstr "" + +msgid "Delete question" +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Details" +msgstr "" + +msgid "Details successfully updated." +msgstr "" + +msgid "Didn't receive confirmation instructions?" +msgstr "" + +msgid "Didn't receive unlock instructions?" +msgstr "" + +msgid "Discard" +msgstr "" + +msgid "Display additional comment area." +msgstr "" + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "" + +msgid "E.g ORCID http://orcid.org/." +msgstr "" + +msgid "Edit" +msgstr "" + +msgid "Edit Annotations" +msgstr "" + +msgid "Edit User Privileges" +msgstr "" + +msgid "Edit customisation" +msgstr "" + +msgid "Edit phase" +msgstr "" + +msgid "Edit phase details" +msgstr "" + +msgid "Edit plan details" +msgstr "" + +msgid "Edit profile" +msgstr "" + +msgid "Edit question" +msgstr "" + +msgid "Edit template details" +msgstr "" + +msgid "Editor" +msgstr "" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "" + +msgid "Email" +msgstr "" + +msgid "Email address" +msgstr "" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "" + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "" + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "" + +msgid "Enter your guidance here. You can include links where needed." +msgstr "" + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "" + +msgid "Error!" +msgstr "" + +msgid "Example Answer" +msgstr "" + +msgid "Example of answer" +msgstr "" + +msgid "Export" +msgstr "" + +msgid "Export settings updated successfully." +msgstr "" + +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "" + +msgid "Face" +msgstr "" + +msgid "File Name" +msgstr "" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "" + +msgid "First name" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Forgot your password?" +msgstr "" + +msgid "Format" +msgstr "" + +msgid "Funder" +msgstr "" + +msgid "Funders templates" +msgstr "" + +msgid "Funding organisation" +msgstr "" + +msgid "Future plans" +msgstr "" + +msgid "Get involved" +msgstr "" + +msgid "Grant number" +msgstr "" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "" + +msgid "Guidance" +msgstr "" + +msgid "Guidance choices saved." +msgstr "" + +msgid "Guidance group" +msgstr "" + +msgid "Guidance group list" +msgstr "" + +msgid "Guidance group was successfully created." +msgstr "" + +msgid "Guidance group was successfully deleted." +msgstr "" + +msgid "Guidance group was successfully updated." +msgstr "" + +msgid "Guidance list" +msgstr "" + +msgid "Guidance was successfully created." +msgstr "" + +msgid "Guidance was successfully deleted." +msgstr "" + +msgid "Guidance was successfully updated." +msgstr "" + +msgid "Hello" +msgstr "" + +msgid "Hello " +msgstr "" + +msgid "Help" +msgstr "" + +msgid "History" +msgstr "" + +msgid "Home" +msgstr "" + +msgid "How many plans?" +msgstr "" + +msgid "How to use the API" +msgstr "" + +msgid "ID" +msgstr "" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "" + +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "" + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "" + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "" + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "" + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "" + +msgid "Included Elements" +msgstr "" + +msgid "Information was successfully created." +msgstr "" + +msgid "Information was successfully deleted." +msgstr "" + +msgid "Information was successfully updated." +msgstr "" + +msgid "Institution" +msgstr "" + +msgid "Invalid font face" +msgstr "" + +msgid "Invalid font size" +msgstr "" + +msgid "Invalid maximum pages" +msgstr "" + +msgid "Invitation to %{email} issued successfully." +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Last logged in" +msgstr "" + +msgid "Last name" +msgstr "" + +msgid "Last updated" +msgstr "" + +msgid "Latest news" +msgstr "" + +msgid "Left" +msgstr "" + +msgid "List of users" +msgstr "" + +msgid "Logo" +msgstr "" + +msgid "Main organisation" +msgstr "" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "" + +msgid "Margin cannot be negative" +msgstr "" + +msgid "Margin value is invalid" +msgstr "" + +msgid "Me" +msgstr "" + +msgid "Message" +msgstr "" + +msgid "Modify guidance" +msgstr "" + +msgid "Modify templates" +msgstr "" + +msgid "Multi select box" +msgstr "" + +msgid "My Plan" +msgstr "" + +msgid "My organisation isn't listed." +msgstr "" + +msgid "My plans" +msgstr "" + +msgid "My research organisation is not on the list" +msgstr "" + +msgid "Name" +msgstr "" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "" + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "" + +msgid "New guidance" +msgstr "" + +msgid "New password" +msgstr "" + +msgid "New section title" +msgstr "" + +msgid "New template" +msgstr "" + +msgid "New to %{application_name}? Create an account today." +msgstr "" + +msgid "No" +msgstr "" + +msgid "No additional comment area will be displayed." +msgstr "" + +msgid "No funder associated with this plan" +msgstr "" + +msgid "No items available." +msgstr "" + +msgid "No matches" +msgstr "" + +msgid "None" +msgstr "" + +msgid "Not answered yet" +msgstr "" + +msgid "Note" +msgstr "" + +msgid "Note removed by" +msgstr "" + +msgid "Note removed by you" +msgstr "" + +msgid "Noted by:" +msgstr "" + +msgid "Ok" +msgstr "" + +msgid "On %{application_name}" +msgstr "" + +msgid "On data management planning" +msgstr "" + +msgid "Optional subset" +msgstr "" + +msgid "Or, sign in with your institutional credentials" +msgstr "" + +msgid "Order" +msgstr "" + +msgid "Order of display" +msgstr "" + +msgid "Organisation" +msgstr "" + +msgid "Organisation details" +msgstr "" + +msgid "Organisation name" +msgstr "" + +msgid "Organisation type" +msgstr "" + +msgid "Organisation was successfully updated." +msgstr "" + +msgid "Organisational" +msgstr "" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "" + +msgid "Organization" +msgstr "" + +msgid "Original funder template has changed!" +msgstr "" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "" + +msgid "Owner" +msgstr "" + +msgid "PDF Formatting" +msgstr "" + +msgid "Password" +msgstr "" + +msgid "Password and comfirmation must match" +msgstr "" + +msgid "Password confirmation" +msgstr "" + +msgid "Permissions" +msgstr "" + +msgid "Phase details" +msgstr "" + +msgid "Plan Data Contact" +msgstr "" + +msgid "Plan Description" +msgstr "" + +msgid "Plan ID" +msgstr "" + +msgid "Plan Name" +msgstr "" + +msgid "Plan data contact" +msgstr "" + +msgid "Plan details" +msgstr "" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "" + +msgid "Plan shared with %{email}." +msgstr "" + +msgid "Plan was successfully deleted." +msgstr "" + +msgid "Plan was successfully updated." +msgstr "" + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +msgid "Please enter a First name." +msgstr "" + +msgid "Please enter a Last name." +msgstr "" + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "" + +msgid "Please enter a valid web address." +msgstr "" + +msgid "Please enter an email address" +msgstr "" + +msgid "Please enter an email address." +msgstr "" + +msgid "Please enter the name of your organisation." +msgstr "" + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "" + +msgid "Please enter your organisation's name." +msgstr "" + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "" + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "" + +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "" + +msgid "Please only enter up to 165 characters, you have used" +msgstr "" + +msgid "Please select an organisation, or select Other." +msgstr "" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "" + +msgid "Primary research organisation" +msgstr "" + +msgid "Principal Investigator / Researcher" +msgstr "" + +msgid "Principal Investigator/Researcher" +msgstr "" + +msgid "Principal Investigator/Researcher ID" +msgstr "" + +msgid "Private" +msgstr "" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "" + +msgid "Privileges" +msgstr "" + +msgid "Project title" +msgstr "" + +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "" + +msgid "Public" +msgstr "" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "" + +msgid "Public DMPs" +msgstr "" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "" + +msgid "Publish" +msgstr "" + +msgid "Publish changes" +msgstr "" + +msgid "Published" +msgstr "" + +msgid "Question" +msgstr "" + +msgid "Question not answered" +msgstr "" + +msgid "Question not answered." +msgstr "" + +msgid "Question number" +msgstr "" + +msgid "Question text" +msgstr "" + +msgid "Question text is empty, please enter your question." +msgstr "" + +msgid "Questions" +msgstr "" + +msgid "Radio buttons" +msgstr "" + +msgid "Read more on the " +msgstr "" + +msgid "Read only" +msgstr "" + +msgid "Releases" +msgstr "" + +msgid "Remember me" +msgstr "" + +msgid "Remove" +msgstr "" + +msgid "Remove user access" +msgstr "" + +msgid "Reset" +msgstr "" + +msgid "Right" +msgstr "" + +msgid "Save" +msgstr "" + +msgid "Save Unsuccessful." +msgstr "" + +msgid "Saving..." +msgstr "" + +msgid "Screencast on how to use %{application_name}" +msgstr "" + +msgid "Section" +msgstr "" + +msgid "Sections" +msgstr "" + +msgid "Select a template" +msgstr "" + +msgid "Select an action" +msgstr "" + +msgid "Select the funding organisation" +msgstr "" + +msgid "Select the primary research organisation responsible" +msgstr "" + +msgid "Select which group this guidance relates to." +msgstr "" + +msgid "Select which theme(s) this guidance relates to." +msgstr "" + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "" + +msgid "Share note" +msgstr "" + +msgid "Share note with collaborators" +msgstr "" + +msgid "Sharing details successfully updated." +msgstr "" + +msgid "Should this guidance apply:" +msgstr "" + +msgid "Sign in" +msgstr "" + +msgid "Sign out" +msgstr "" + +msgid "Signed in as " +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Someone has requested a link to change your " +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "" + +msgid "Suggested answer/ Example" +msgstr "" + +msgid "Super admin area" +msgstr "" + +msgid "Template" +msgstr "" + +msgid "Template History" +msgstr "" + +msgid "Template details" +msgstr "" + +msgid "Templates" +msgstr "" + +msgid "Terms of use" +msgstr "" + +msgid "Test/Practice" +msgstr "" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "" + +msgid "Text" +msgstr "" + +msgid "Text area" +msgstr "" + +msgid "Text field" +msgstr "" + +msgid "Thank you for registering. Please confirm your email address" +msgstr "" + +msgid "That email address is already registered." +msgstr "" + +msgid "That template is not currently published." +msgstr "" + +msgid "The" +msgstr "" + +msgid "The " +msgstr "" + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "" + +msgid "The following answer cannot be saved" +msgstr "" + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "" + +msgid "Themes" +msgstr "" + +msgid "There are no public DMPs." +msgstr "" + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "" + +msgid "These are the basic details for your organisation." +msgstr "" + +msgid "This allows you to order questions within a section." +msgstr "" + +msgid "This allows you to order sections." +msgstr "" + +msgid "This allows you to order the phases of your template." +msgstr "" + +msgid "This document was generated by %{application_name}" +msgstr "" + +msgid "This must match what you entered in the previous field." +msgstr "" + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "" + +msgid "This plan is based on the default template." +msgstr "" + +msgid "This plan is based on:" +msgstr "" + +msgid "This section is locked for editing by " +msgstr "" + +msgid "Title" +msgstr "" + +msgid "Top" +msgstr "" + +msgid "Top banner text" +msgstr "" + +msgid "Transfer customisation" +msgstr "" + +msgid "Un-published" +msgstr "" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "" + +msgid "Unknown formatting setting" +msgstr "" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "" + +msgid "Unlink account" +msgstr "" + +msgid "Unlink institutional credentials alert" +msgstr "" + +msgid "Unlock my account" +msgstr "" + +msgid "Unpublish" +msgstr "" + +msgid "Unpublished" +msgstr "" + +msgid "Unpublished changes" +msgstr "" + +msgid "Unsaved answers" +msgstr "" + +msgid "Unsaved changes" +msgstr "" + +msgid "Upload a new logo file" +msgstr "" + +msgid "Users" +msgstr "" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "" + +msgid "View" +msgstr "" + +msgid "View all guidance" +msgstr "" + +msgid "View all templates" +msgstr "" + +msgid "View phase" +msgstr "" + +msgid "View plans" +msgstr "" + +msgid "Visibility" +msgstr "" + +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "" + +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "" + +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "" + +msgid "Website" +msgstr "" + +msgid "Welcome to " +msgstr "" + +msgid "Welcome to %{application_name}" +msgstr "" + +msgid "Welcome." +msgstr "" + +msgid "What research project are you planning?" +msgstr "" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "" + +msgid "Which DMP template would you like to use?" +msgstr "" + +msgid "Would you like to save them now?" +msgstr "" + +msgid "Yes" +msgstr "" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "" + +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "" + +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "" + +msgid "You are not authorized to perform this action." +msgstr "" + +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "" + +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "" + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "" + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "" + +msgid "You can edit any of the details below." +msgstr "" + +msgid "You can not continue until you have filled in all of the required information." +msgstr "" + +msgid "You can not edit a historical version of this template." +msgstr "" + +msgid "You can not publish a historical version of this template." +msgstr "" + +msgid "You cannot delete historical versions of this template." +msgstr "" + +msgid "You have altered answers but have not saved them:" +msgstr "" + +msgid "You have been given " +msgstr "" + +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "" + +msgid "You have un-published changes" +msgstr "" + +msgid "You have unsaved answers in the following sections:" +msgstr "" + +msgid "You must accept the terms and conditions to register." +msgstr "" + +msgid "You must enter a valid email address." +msgstr "" + +msgid "You need to sign in or sign up before continuing." +msgstr "" + +msgid "You now have " +msgstr "" + +msgid "Your" +msgstr "" + +msgid "Your ORCID" +msgstr "" + +msgid "Your access to " +msgstr "" + +msgid "Your account has been successfully linked to %{scheme}." +msgstr "" + +msgid "Your account won't be created until you access the link above and set your password." +msgstr "" + +msgid "Your browser does not support the video tag." +msgstr "" + +msgid "Your password must contain at least 8 characters." +msgstr "" + +msgid "Your permissions relating to " +msgstr "" + +msgid "Your template has been published and is now available to users." +msgstr "" + +msgid "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" +msgstr "" + +msgid "a day" +msgstr "" + +msgid "about %d hours" +msgstr "" + +msgid "about a minute" +msgstr "" + +msgid "about a month" +msgstr "" + +msgid "about a year" +msgstr "" + +msgid "about an hour" +msgstr "" + +msgid "account has been locked due to an excessive number of unsuccessful sign in attempts." +msgstr "" + +msgid "activerecord.errors.messages.record_invalid" +msgstr "" + +msgid "activerecord.errors.models.user.attributes.current_password.invalid" +msgstr "" + +msgid "activerecord.errors.models.user.attributes.email.blank" +msgstr "" + +msgid "activerecord.errors.models.user.attributes.password.blank" +msgstr "" + +msgid "activerecord.errors.models.user.attributes.password_confirmation.confirmation" +msgstr "" + +msgid "add guidance text" +msgstr "" + +msgid "ago" +msgstr "" + +msgid "approx. %{space_used}%% of available space used (max %{num_pages} pages)" +msgstr "" + +msgid "by " +msgstr "" + +msgid "can't be blank" +msgstr "" + +msgid "can't be larger than 500KB" +msgstr "" + +msgid "can't be less than zero" +msgstr "" + +msgid "e.g. School/ Department" +msgstr "" + +msgid "example answer" +msgstr "" + +msgid "from now" +msgstr "" + +msgid "generic template" +msgstr "" + +msgid "guidance" +msgstr "" + +msgid "guidance group" +msgstr "" + +msgid "guidance on" +msgstr "" + +msgid "height must be less than 100px" +msgstr "" + +msgid "helpers.is_test" +msgstr "" + +msgid "helpers.links.cancel" +msgstr "" + +msgid "helpers.project.is_test_help_text" +msgstr "" + +msgid "into your browser" +msgstr "" + +msgid "less than a minute" +msgstr "" + +msgid "must be logged in" +msgstr "" + +msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" +msgstr "" + +msgid "must be unique" +msgstr "" + +msgid "must have access to guidances api" +msgstr "" + +msgid "must have access to plans api" +msgstr "" + +msgid "no research organisation is associated with this plan" +msgstr "" + +msgid "note" +msgstr "" + +msgid "or copy" +msgstr "" + +msgid "organisation" +msgstr "" + +msgid "phase" +msgstr "" + +msgid "plan" +msgstr "" + +msgid "profile" +msgstr "" + +msgid "question" +msgstr "" + +msgid "questions answered" +msgstr "" + +msgid "role" +msgstr "" + +msgid "section" +msgstr "" + +msgid "select a guidance group" +msgstr "" + +msgid "select at least one theme" +msgstr "" + +msgid "since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again." +msgstr "" + +msgid "template" +msgstr "" + +msgid "user" +msgstr "" + +msgid "user must be in your organisation" +msgstr "" diff --git a/config/locale/de/app.po b/config/locale/de/app.po new file mode 100644 index 0000000..b28632b --- /dev/null +++ b/config/locale/de/app.po @@ -0,0 +1,1835 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2017-05-02 14:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr "" + +msgid " - " +msgstr " - " + +#, fuzzy +msgid " I accept the terms and conditions *" +msgstr "Ich akzeptiere die Nutzungsbedingungen *" + +#, fuzzy +msgid " Plan" +msgstr "plans" + +msgid " access to" +msgstr "" + +msgid " access. " +msgstr "" + +msgid " and " +msgstr "" + +#, fuzzy +msgid " by" +msgstr " von " + +msgid " by " +msgstr " von " + +#, fuzzy +msgid " has been removed by " +msgstr " von " + +#, fuzzy +msgid " have been changed by" +msgstr " von " + +#, fuzzy +msgid " into your browser)" +msgstr "into your browser)." + +msgid " on " +msgstr "" + +msgid " or " +msgstr "" + +#, fuzzy +msgid " password. You can do this through the link below." +msgstr "password. You can do this through the link below." + +#, fuzzy +msgid " provided by " +msgstr " von " + +#, fuzzy +msgid " team" +msgstr "am" + +#, fuzzy +msgid " that has been customised by " +msgstr " von " + +#, fuzzy +msgid " to accept the invitation, (or copy " +msgstr "(or copy" + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr "" + +#, fuzzy +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "ID" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "" + +#, fuzzy +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "Your " + +msgid "%d days" +msgstr "" + +msgid "%d minutes" +msgstr "" + +msgid "%d months" +msgstr "" + +msgid "%d years" +msgstr "" + +msgid "%{application_name}" +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "DMPonline" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "" + +msgid "%{value} is not a valid format" +msgstr "" + +msgid "(Using custom PDF formatting values)" +msgstr "(Verwende eigene Werte bei PDF-Formatierung)" + +msgid "(Using template PDF formatting values)" +msgstr "(Verwende Vorlagenwerte bei PDF-Formatting)" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "

    Zu berücksichtigende Fragen:

    • - Welcher Art ist Ihr Forschungsproject?
    • - Welche Forschungsfragen sollen im Projekt bearbeitet werden?
    • - Welchem Zweck werden die erzeugten oder gesammelt Daten dienen?

    Hilfestellung:

    Fassen Sie die Art der Studien / Untersuchungen zusammen, um Dritten den Zweck der erzeugten oder gesammelt Daten zu veranschaulichen.

    " + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "
    Geben Sie eine kurze Beschreibung an. Diese sollte zusammenfassen, was von diesem Abschnitt abgedeckt wird, oder Hinweise zur Beantwortung der Fragen geben. Dieser Text wird ein einem farbigen Banner angezeigt, sobald ein Abschnitt zur Bearbeitung geöffnet wird." + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "
    Geben Sie eine Beschreibung ein, die Ihnen bei der Unterscheidung von Vorlagen hilft, falls Sie z.B. welche für unterschiedliche Zielgruppen besitzen.
    " + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "

    Dies ist eine Testinstallation von DMPonline. DMPonline wird vom Digital Curation Centre (DCC) entwickelt und gepflegt und steht unter einer AGPL Lizenz als Open Source Software zur Verfügung.

    Die Testinstallation dient lediglich der Weiterentwicklung und Evaluation der Software und ist nicht für den Produktiveinsatz gedacht.

    Zu Ihrer persönlichen Information

    Diese Testinstallation wird in absehbarer Zeit wieder abgeschaltet werden. Die Daten, die in dieser Installation erstellt wurden, werden bei der Abschaltung verloren gehen. Wichtige Daten sollten nicht ausschließlich in der Testinstallation gespeichert werden.

    " + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "

    Datenmanagementplan-Anleitung am Beispiel von Horizon 2020

    • Datenmanagementplan-Anleitung (PDF)
      Der Computer- und Medienservice der Humboldt-Universität zu Berlin hat eine Anleitung zur Erstellung eines Datenmanagementplans (DMP) in Horizon 2020 mit DMPonline bereit gestellt.

    Useful resources on Data Management Planning

    Example Data Management Plans

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the DCC on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "

    DMPonline wurde vom Digital Curation Centre entwickelt, um Sie bei der Erstellung von Data-Managment-Plänen zu unterstützen.

    " + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "" + +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "

    Geschichten zu DMPonline auf der DCC-Seite


    " + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "

    Willkommen.
    Sie können nun ihren ersten DMP erstellen.
    Wählen Sie 'Plan erstellen' weiter unten aus, um zu beginnen.

    " + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "

    Erstelle zuerst eine Hilfestellungsgruppe. Diese könnte institutionsweit oder eine Untermenge von z.B. einer bestimmten Universität / Schule, eines Instituts oder einer Abteilung sein. Wenn Sie Hilfestellung erstellen, werden sie aufgefordert sie einer Hilfestellungsgruppe zuzuordnen.

    " + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "

    Hier können Sie Ihren Plan in verschiedenen Formaten herunterladen. Das kann nützlich sein, falls Sie den Plan als Teil Ihres Projektantrags einreichen müssen.
    Wählen Sie das gewünschte Format aus und wählen Sie 'Exportieren'.

    " + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "

    Fördergeber verlangen zunehmend die Erstellung von Datenmanagementplänen von den Antragstellern, bzw. Förderempfängern, sowohl in der Antragsphase als auch während der Durchführung. DMPonline wurde vom Digital Curation Centre (UK) erstellt, um es Forschenden zu ermöglichen, auf diese Anforderungen zu reagieren und dabei auch die Vorgaben ihrer Institutionen oder anderen Beteiligten zu erfüllen.

    Die Entwicklung fand in Kooperation mit Forschungsförderern und Universitäten statt, um ein Werkzeug für die Erstellung von probaten Datenmanagementplänen während des gesamten Projektverlaufs anbieten zu können.

    Konzept

    Es gibt eine Reihe von Vorlagen innerhalb der Applikation, die den Anforderungen der verschiedenen Förderer oder Institutionen entsprechen. Die Nutzer beantworten zu Begin der Erstellung eines Plans drei Fragen, um die Anzeige der geeigneten Vorlage zu erlauben (z.B. die ESRC-Vorlage bei einer ESRC-Förderung). Die Applikation gibt Hilfestellungen zum Verstehen und Beantworten der Fragen; diese werden von Forschenden, Förderern, Universitäten und den verschiedenen Disziplinen bereitgestellt.

    Erste Schritte

    Falls sie einen Zugang haben, melden sie sich an und beginnen ihren Datenmanagementplan zu erstellen.

    Falls sie keinen Zugang zu DMPonline haben, wählen sie 'Registrieren' auf der Startseite aus.

    Besuchen sie die 'Hilfe'-Seite für eine Anleitung.

    Weitere Informationen

    Die deutsche Version von DMPonline wird in Kooperation mit dem Digital Curation Centre (UK) und der Bibliothek der Universität von Alberta (CA) im Rechenzentrum der Christian-Albrechts-Universität gepflegt.

    Die Benutzungsschnittstelle und die Funktionalität von DMPonline wird kontinuierlich verbessert. Falls sie gerne Rückmeldung geben oder Verbesserungsvorschläge machen möchten, freuen wir uns, wenn sie uns eine Nachricht an vfu@rz.uni-kiel.de schicken.

    " + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "" + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "

    Dieser Titel wird den Nutzern angezeigt. Falls Sie mehrere Phasen für einen DMP haben wollen, sollte dies aus dem Titel und der Beschreibung hervorgehen.

    " + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "

    Falls Sie eine Vorlage für eine Institution anlegen möchten, können Sie den Knopf 'Vorlage erstellen' nutzen. Sie können verschiedene Vorlagen erstellen um auf Spezialisierungen einzugehen, z.B. für Forscher und für Doktoranden.

    " + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "

    Wählen Sie die für diese Frage relevanten Themen aus.

    Dies erlaubt es, sowohl generischen Hilfestellungen auf Institutions-Ebene, als auch aus anderen Quellen, wie z.B. der DINI, oder jedweder Institute oder Einrichtungen, für die Sie Unterstützung anbieten, einzubeziehen.

    Sie können mehrere Themen durch klicken und gleichzeitiges Drücken der Steuerungs- bzw. Kommando-Taste auswählen.

    " + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "" + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "

    Die folgende Tabelle listet alle von Ihnen erstellten und von anderen mit Ihnen geteilten Pläne.
    Diese können jederzeit bearbeitet, geteilt, exportiert und gelöscht werden.

    " + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "

    Um eine Vorlage anzulegen beginnen sie mit einem Titel und einer Beschreibung. Nach dem Speichern haben Sie die Option zum Anlegen von ein oder mehreren Phasen.

    " + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "

    Nach der Anmeldung in DMPonline werden sie zur 'Meine Pläne'-Seite weitergeleitet. Dies ist der Startpunkt, um ihre Pläne zu Edieren, zu Teilen oder zu löschen. Sie sehen außerdem, welche Pläne sie mit anderen geteilt haben.

    Pläne erstellen

    Um einen Plan zu erstellen, klicken sie auf den 'Plan erstellen'-Knopf auf der 'Meine Pläne'-Seite, oder im Hauptmenü. Wählen sie die passenden Optionen in den Ausklappmenüs und Auswahlboxen aus, um zu bestimmen, welche Fragen und Hilfestellungen ihnen angezeigt werden sollen. Bestätigen sie ihre Auswahl durch das Klicken von 'Ja, Plan erstellen'.

    Pläne schreiben

    Die Reiter der Benutzerschnittstelle erlauben ihnen durch die verschiedenen Bereiche zu navigieren wenn sie ihren Plan bearbeiten.

    • - 'Plandetails' enthält die grundliegenden administrativen Details, listet die Fragen und Hilfestellungen, auf denen ihr Plan basiert und gibt eine Übersicht über die zu beantwortenden Fragen
    • - die folgenden Reiter repräsentieren die zu beantwortenden Fragen. Sollten ihr Förderer oder ihre Institution verschiedene Fragen zu verschiedenen Stufen des Plans beantwortet wissen möchten, können hier mehrere Reiter auftauchen
    • - 'Teilen' enthält Details zum Einladen von anderen Personen zum Lesen oder zur aktiven Mitabeit am Plan
    • - 'Export' enthält Möglichkeiten zum Export des Plans in verschiedene Dateiformate. Dies kann nützlich sein, wenn sie ihren Plan im Rahmen eines Antrags einreichen müssen

    In den Fragereitern sind die verschiedenen Abschnitte ihres Plans dargestellt, die sich durch anklicken zur Bearbeitung auswählen lassen. Die Antworttexte können mit den Textbearbeitungsknöpfen formatiert werden.

    Hilfestellungen werden rechts von den Fragen durch klicken des '+'-Symbols angezeigt.

    Bitte vergessen sie nicht ihre Antworten zu speichern, bevor sie die Seite verlassen.

    Pläne teilen

    Geben sie die E-Mail-Adresse der Person an, die ihren Plan lesen oder bearbeiten können sollen. Mithilfe des Ausklappmenüs können sie die Befugnisse, die die Person im Bezug auf den Plan haben soll, auswählen. Klicken sie abschließend auf 'Mitarbeitende(n) hinzufügen'.

    Pläne exportieren

    Wählen sie das Dateiformat aus, in das sie ihren Plan exportieren möchten und klicken sie 'Export'. Unterhalb des Dialogs können sie durch klicken auf das '+'-Symbol detaillierte Einstellungen zum Export vornehmen.

    " + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "

    You are about to unlink DMP Builder of your institutional credentials, would you like to continue?

    " + +#, fuzzy +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "

    Sie können anderen Zugriff zu Ihren Plan gewähren. Es gibt hierbei drei Abstufungen des Zugriffs.

    • Benutzer mit 'nur lesen'-Rechten können den Plan nur lesen.
    • Bearbeiter können zum Plan beitragen.
    • Miteigentümer können zum Plan beitragen und zusätzlich die Plandetails und die Zugriffsrechte bearbeiten.

    Neue Mitarbeitende können durch die Angabe ihrer E-Mail-Adresse und das Wählen des Zugriffsrechts hinzugefugt werden. Bestätigen Sie Ihre Angaben mit 'Mitarbeitende(n) hinzufügen'

    Eingeladene Mitarbeitende erhalten eine E-Mail, die sie darüber informiert, dass sie Zugriff zu Ihrem Plan erhalten haben; sofern Mitarbeitende noch nicht bei DMPonline registriert sind, erhalten sie eine Einladung zur Registrierung. Wenn die Zugriffsrechte geändert werden wird ebenfalls eine Benachrichtigungs-E-Mail versand.

    " + +#, fuzzy +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "templates" + +#, fuzzy +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "DMPonline" + +#, fuzzy +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "DMPonline" + +#, fuzzy +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "A colleague has invited you to contribute to their Data Management Plan at" + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "Eine Identifikationskürzel, wie es von Förderern oder Institutionen vergeben wird." + +msgid "A required setting has not been provided" +msgstr "Eine benötigte Einstellung wurde nicht erbracht" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "" + +msgid "Abbreviation" +msgstr "Abkürzung" + +msgid "About" +msgstr "Über uns" + +msgid "About %{application_name}" +msgstr "Über DMPonline" + +msgid "Access removed" +msgstr "" + +msgid "Actions" +msgstr "Aktionen" + +msgid "Add Annotations" +msgstr "" + +#, fuzzy +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "Hilfestellungsgruppe" + +msgid "Add collaborator" +msgstr "Mitarbeitende(n) hinzufügen" + +msgid "Add guidance" +msgstr "Hilfestellung hinzufügen" + +msgid "Add guidance group" +msgstr "Gruppe für Hilfestellungen hinzufügen" + +msgid "Add new phase +" +msgstr "Neue Phase hinzufügen" + +msgid "Add note" +msgstr "Füge Kommentar hinzu" + +msgid "Add option" +msgstr "Option hinzufügen" + +msgid "Add question" +msgstr "Frage hinzufügen" + +msgid "Add section" +msgstr "Abschnitt hinzufügen" + +msgid "Additional comment area will be displayed." +msgstr "" + +msgid "Admin Details" +msgstr "" + +msgid "Admin area" +msgstr "Administativer Bereich" + +msgid "All the best," +msgstr "" + +#, fuzzy +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "Organisation" + +#, fuzzy +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "Organisation" + +#, fuzzy +msgid "Allows the user to create and edit guidance" +msgstr "user" + +#, fuzzy +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "templates" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +#, fuzzy +msgid "Answer" +msgstr "Antworten" + +msgid "Answer format" +msgstr "Antwortform" + +msgid "Answer questions" +msgstr "Fragen beantworten" + +#, fuzzy +msgid "Answered" +msgstr "Beantwortet " + +#, fuzzy +msgid "Answered at" +msgstr "Beantwortet " + +#, fuzzy +msgid "Answered by" +msgstr "Beantwortet " + +msgid "Answers" +msgstr "Antworten" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "Alles, was Sie hier eingeben, wird im Antwortfeld erscheinen. Falls Sie eine Antwort in einem bestimmten Format haben möchten (z.B. als Tabelle) können Sie diesen Stil hier angeben." + +msgid "Are you sure you want to remove this note?" +msgstr "" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "Sind Sie sicher, dass sie diesen Plan löschen wollen?" + +msgid "Are you sure?" +msgstr "Sind Sie sicher?" + +msgid "Back" +msgstr "Zurück" + +msgid "Back to edit view" +msgstr "Zurück, um die Ansicht zu bearbeiten" + +msgid "Background" +msgstr "Hintergrund" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "" + +#, fuzzy +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "Fragen" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "Folgend findet sich die Liste von Benutzern registriert bzgl. Ihrer Org. Sie können diese Liste bzgl. aller Felder sortieren." + +msgid "Bottom" +msgstr "Unten" + +msgid "By " +msgstr "" + +msgid "Cancel" +msgstr "Abbrechen" + +#, fuzzy +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "plans" + +msgid "Change language" +msgstr "" + +#, fuzzy +msgid "Change my password" +msgstr "Passwort ändern" + +#, fuzzy +msgid "Change organisation details" +msgstr "Organisation" + +msgid "Check box" +msgstr "Checkbox" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "Markieren Sie dieses Kästchen, wenn Sie bereit sind, für diese Anleitung für Benutzer-Pläne zu erscheinen." + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "Click here to accept the invitation" + +msgid "Click here to confirm your account" +msgstr "Click here to confirm your account" + +#, fuzzy +msgid "Click the link below to unlock your account" +msgstr "Click the link below to unlock your account:" + +msgid "Co-owner" +msgstr "Miteigentümer" + +msgid "Collaborators" +msgstr "Mitarbeitende" + +msgid "Comment" +msgstr "Kommentar" + +#, fuzzy +msgid "Comment removed." +msgstr "Kommentar" + +msgid "Comment was successfully created." +msgstr "" + +#, fuzzy +msgid "Comment was successfully saved." +msgstr "Plan wurde erfolgreich angelegt." + +msgid "Contact Email" +msgstr "Kontakt Email" + +#, fuzzy +msgid "Contact Us" +msgstr "Kontakt" + +msgid "Contact us" +msgstr "Kontakt" + +msgid "Create a new plan" +msgstr "Einen neuen Plan erstellen" + +msgid "Create a template" +msgstr "Vorlage erstellen" + +msgid "Create account" +msgstr "Registrieren" + +msgid "Create plan" +msgstr "Erstelle Plan" + +msgid "Created" +msgstr "Erstellt" + +msgid "Created at" +msgstr "Angelegt am" + +msgid "Current password" +msgstr "Aktuelles Passwort" + +msgid "Customise" +msgstr "Anpassen" + +msgid "Default" +msgstr "Vorgabe" + +msgid "Default answer" +msgstr "Vorauswahl" + +msgid "Default value" +msgstr "Wertvorgabe" + +msgid "Delete" +msgstr "Löschen" + +#, fuzzy +msgid "Delete Example Answer" +msgstr "Beispielantwort" + +msgid "Delete question" +msgstr "Frage löschen" + +msgid "Description" +msgstr "" + +msgid "Details" +msgstr "Details" + +msgid "Details successfully updated." +msgstr "" + +msgid "Didn't receive confirmation instructions?" +msgstr "Bestätigungsanleitungen nicht erhalten?" + +msgid "Didn't receive unlock instructions?" +msgstr "Entsperrungsanleitungen nicht erhalten?" + +msgid "Discard" +msgstr "Verwerfen" + +msgid "Display additional comment area." +msgstr "" + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "Klappliste" + +msgid "E.g ORCID http://orcid.org/." +msgstr "z.B. die ORCID (http://orcid.org/)." + +msgid "Edit" +msgstr "Bearbeiten" + +#, fuzzy +msgid "Edit Annotations" +msgstr "Bearbeiten" + +msgid "Edit User Privileges" +msgstr "Bearbeiten Benutzerberechtigungen" + +msgid "Edit customisation" +msgstr "Anpassungen bearbeiten" + +msgid "Edit phase" +msgstr "Phase bearbeiten" + +msgid "Edit phase details" +msgstr "Details der Phase bearbeiten" + +msgid "Edit plan details" +msgstr "Plandetails bearbeiten" + +msgid "Edit profile" +msgstr "Profil bearbeiten" + +msgid "Edit question" +msgstr "Frage bearbeiten" + +msgid "Edit template details" +msgstr "Details der Vorlage bearbeiten" + +#, fuzzy +msgid "Editor" +msgstr "Bearbeiten" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "Editoren können zu Plan beitragen. Miteigentümer haben zusätzliche Rechte um Plandetails und Zugriffsrechte bearbeiten zu können." + +msgid "Email" +msgstr "E-Mail" + +msgid "Email address" +msgstr "E-Mail-Adresse" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "Geben Sie eine kurze Beschreibung an. Diese wird den Nutzern oberhalb der Zusammenfassung der Abschnitte und der Fragen, die sie beantowrten müssen, angezeigt." + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "Geben Sie eine Beschreibung, die hilft, zwischen den verschiedenen Vorlagen zu unterscheiden, z.B. für verschiedene Zielgruppen" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "Geben Sie einen Titel für die Phase an, z.B. Initialer DMP oder Kompletter DMP. Die Titel werden den Benutzern in den Reitern angezeigt, während sie einen Plan erstellen. Falls Sie nur eine Phase bereitstellen, geben Sie ihm einen allgemeinen Titel wie z.B. 'CAU DMP'" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "Geben Sie alle Optionen an, die angezeigt werden sollen. Sie können eine der Option als Vorauswahl mit Hilfe der entsprechenden Checkbox markieren." + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "Geben Sie spezifische Hilfestellung an, die diese Frage begleiten soll. Falls Sie auch Hilfestellungen nach Themen angeben, werden diese mit angezeigt; Sie sollten deshalb möglichst wenig Text kopieren." + +msgid "Enter your guidance here. You can include links where needed." +msgstr "Hilfestellung hier eingeben; Verweise auf andere Web-Seiten können integriert werden." + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "" + +msgid "Error!" +msgstr "Fehler!" + +#, fuzzy +msgid "Example Answer" +msgstr "Beispielantwort" + +#, fuzzy +msgid "Example of answer" +msgstr "Beispielantwort" + +msgid "Export" +msgstr "Export" + +#, fuzzy +msgid "Export settings updated successfully." +msgstr "Export" + +#, fuzzy +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "Export" + +msgid "Face" +msgstr "Schriftart" + +msgid "File Name" +msgstr "Dateiname" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "Filter Pläne" + +msgid "First name" +msgstr "Vorname" + +msgid "Font" +msgstr "Schrift" + +msgid "Forgot your password?" +msgstr "Passwort vergessen?" + +msgid "Format" +msgstr "" + +msgid "Funder" +msgstr "Funder" + +msgid "Funders templates" +msgstr "Vorlagen der Geldgeber" + +#, fuzzy +msgid "Funding organisation" +msgstr "Organisation" + +msgid "Future plans" +msgstr "" + +msgid "Get involved" +msgstr "" + +msgid "Grant number" +msgstr "Grantnummer" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "Das Förderkennzeichen als Referenz, sofern sinnvoll (Nur für Datenmanagement-Pläne nach der Bewilligung)." + +msgid "Guidance" +msgstr "Hilfestellung" + +#, fuzzy +msgid "Guidance choices saved." +msgstr "Hilfestellung" + +msgid "Guidance group" +msgstr "Hilfestellungsgruppe" + +msgid "Guidance group list" +msgstr "Liste der Gruppen für Hilfestellungen" + +msgid "Guidance group was successfully created." +msgstr "Hilfestellungsgruppe erfolgreich erzeugt." + +msgid "Guidance group was successfully deleted." +msgstr "Hilfestellungsgruppe erfolgreich gelöscht." + +msgid "Guidance group was successfully updated." +msgstr "Hilfestellungsgruppe erfolgreich aktualisiert." + +msgid "Guidance list" +msgstr "Liste der Hilfestellungen" + +msgid "Guidance was successfully created." +msgstr "Hilfestellung erfolgreich angelegt." + +#, fuzzy +msgid "Guidance was successfully deleted." +msgstr "Hilfestellung erfolgreich angelegt." + +msgid "Guidance was successfully updated." +msgstr "Hilfestellung erfolgreich aktualisiert." + +msgid "Hello" +msgstr "Hello" + +#, fuzzy +msgid "Hello " +msgstr "Hello" + +msgid "Help" +msgstr "Hilfe" + +msgid "History" +msgstr "" + +msgid "Home" +msgstr "Start" + +msgid "How many plans?" +msgstr "Wie viele Pläne?" + +msgid "How to use the API" +msgstr "" + +msgid "ID" +msgstr "ID" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "Falls Sie einen Förderantrag stellen, geben Sie bitte den Namen exakt genau so an, wie im Förderantrag." + +#, fuzzy +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "Falls Sie einen Förderantrag stellen, geben Sie bitte den Namen exakt genau so an, wie im Förderantrag." + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "Falls die Hilfestellung nur für eine bestimmte Nutzergruppe, wie z.B. eine bestimmte Fakultät oder ein Institut, bestimmt ist, wählen Sie diese Option aus. Die Nutzer können die Anzeige von Hilfestellungen dieser Untergruppe im 'Plan erstellen'-Assistenten auswählen." + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "Wenn Sie die Standard DMPRoadmap Logo verwenden entscheiden , prüfen Sie bitte dieses Feld Ihre aktuelle Logo zu entfernen." + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "Zum Ändern Ihres Passworts folgende Felder ausfüllen." + +msgid "Included Elements" +msgstr "Enthaltene Elemente" + +msgid "Information was successfully created." +msgstr "Information wurde erfolgreich angelegt." + +msgid "Information was successfully deleted." +msgstr "Information wurde erfolgreiche entfernt." + +msgid "Information was successfully updated." +msgstr "Information wurde erfolgreich aktuallisiert" + +msgid "Institution" +msgstr "Institution" + +msgid "Invalid font face" +msgstr "Ungültige Schriftart" + +msgid "Invalid font size" +msgstr "Ungültige Schriftgröße" + +msgid "Invalid maximum pages" +msgstr "Ungültige maximale Anzahl von Seiten" + +msgid "Invitation to %{email} issued successfully." +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Last logged in" +msgstr "Zuletzt angemeldet" + +msgid "Last name" +msgstr "Nachname" + +msgid "Last updated" +msgstr "Zuletzt aktualisiert" + +msgid "Latest news" +msgstr "Neuigkeiten" + +msgid "Left" +msgstr "Links" + +msgid "List of users" +msgstr "Liste der Nutzer" + +msgid "Logo" +msgstr "Logo" + +msgid "Main organisation" +msgstr "Übergeordnete Organisation" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "Rand" + +msgid "Margin cannot be negative" +msgstr "Rand darf nicht negativ sein" + +msgid "Margin value is invalid" +msgstr "Randwert ist ungültig" + +msgid "Me" +msgstr "Ich" + +#, fuzzy +msgid "Message" +msgstr "Ich" + +#, fuzzy +msgid "Modify guidance" +msgstr "Hilfestellung hinzufügen" + +#, fuzzy +msgid "Modify templates" +msgstr "templates" + +msgid "Multi select box" +msgstr "Mehrfachauswahlliste" + +#, fuzzy +msgid "My Plan" +msgstr "Mein Plan" + +msgid "My organisation isn't listed." +msgstr "Meine Organisation ist nicht in der Auflistung." + +msgid "My plans" +msgstr "Meine Pläne" + +#, fuzzy +msgid "My research organisation is not on the list" +msgstr "Organisation" + +msgid "Name" +msgstr "Name" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "Name (falls abweichend von obigen Angaben), Telefonnummer und E-Mail-Adresse." + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "Name des Principal Investigators oder der Leitung des Projektes." + +msgid "New guidance" +msgstr "Neue Hilfestellung" + +msgid "New password" +msgstr "Neues Passwort" + +msgid "New section title" +msgstr "Neue Abschnittsüberschrift" + +msgid "New template" +msgstr "Neue Vorlage" + +msgid "New to %{application_name}? Create an account today." +msgstr "Neu auf DMPonline? Heute noch registrieren." + +msgid "No" +msgstr "" + +msgid "No additional comment area will be displayed." +msgstr "" + +#, fuzzy +msgid "No funder associated with this plan" +msgstr "plans" + +msgid "No items available." +msgstr "" + +msgid "No matches" +msgstr "Kein Plan erfüllt '%{filter}'" + +msgid "None" +msgstr "Keines" + +msgid "Not answered yet" +msgstr "Noch nicht beantwortet" + +msgid "Note" +msgstr "Kommentar" + +msgid "Note removed by" +msgstr "Kommentar entfernt von" + +msgid "Note removed by you" +msgstr "Kommentar von Ihnen entfernt" + +msgid "Noted by:" +msgstr "Kommentar von:" + +msgid "Ok" +msgstr "" + +msgid "On %{application_name}" +msgstr "DMPonline" + +msgid "On data management planning" +msgstr "Datenmanagement-Planung" + +msgid "Optional subset" +msgstr "Optionale Untergruppe" + +msgid "Or, sign in with your institutional credentials" +msgstr "Oder melden Sie sich mit den Zugangsdaten Ihres Instituts an" + +msgid "Order" +msgstr "Reihenfolge" + +msgid "Order of display" +msgstr "Reihenfolge" + +msgid "Organisation" +msgstr "Organisation" + +msgid "Organisation details" +msgstr "Organisations-Details" + +msgid "Organisation name" +msgstr "Name der Organisation" + +msgid "Organisation type" +msgstr "Organisationsart" + +msgid "Organisation was successfully updated." +msgstr "Organisation wurde erfolgreich aktualisiert." + +msgid "Organisational" +msgstr "Organisatorische" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "Mit anderen innerhalb Ihrer Organisation" + +msgid "Organization" +msgstr "Organisation" + +#, fuzzy +msgid "Original funder template has changed!" +msgstr "templates" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "Eigene Vorlagen" + +msgid "Owner" +msgstr "Besitzer" + +msgid "PDF Formatting" +msgstr "PDF Formatierung" + +msgid "Password" +msgstr "Passwort" + +#, fuzzy +msgid "Password and comfirmation must match" +msgstr "Passwort" + +msgid "Password confirmation" +msgstr "Passwort bestätigen" + +msgid "Permissions" +msgstr "Zugriffsrechte" + +msgid "Phase details" +msgstr "Details der Phase" + +msgid "Plan Data Contact" +msgstr "Kontakt für Planen" + +msgid "Plan Description" +msgstr "Beschreibung" + +msgid "Plan ID" +msgstr "Planenbezeichner" + +msgid "Plan Name" +msgstr "Planenname" + +msgid "Plan data contact" +msgstr "Plandatenkontakt" + +msgid "Plan details" +msgstr "Plandetails" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "Name des Plans" + +msgid "Plan shared with %{email}." +msgstr "" + +#, fuzzy +msgid "Plan was successfully deleted." +msgstr "Plan wurde erfolgreich angelegt." + +msgid "Plan was successfully updated." +msgstr "" + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +#, fuzzy +msgid "Please enter a First name." +msgstr "Bitte geben Sie ihren Vornamen ein." + +#, fuzzy +msgid "Please enter a Last name." +msgstr "Bitte geben Sie ihren Vornamen ein." + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "Bitte geben sie einen Titel für Ihre Vorlage an." + +msgid "Please enter a valid web address." +msgstr "Bitte prüfen Sie die Korrektheit ihrer Web-Adresse." + +msgid "Please enter an email address" +msgstr "" + +#, fuzzy +msgid "Please enter an email address." +msgstr "Bitte prüfen Sie die Korrektheit ihrer Web-Adresse." + +msgid "Please enter the name of your organisation." +msgstr "Bitte geben Sie den Namen Ihrer Organisation an." + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "Bitte geben Sie ihren Vornamen ein." + +msgid "Please enter your organisation's name." +msgstr "Bitte geben Sie den Namen Ihrer Organisation an." + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "Bitte geben Sie ihren Familien- bzw. Nachnamen ein." + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "Bitte geben Sie im Folgenden die Projektdetails an und wählen 'Aktualisieren' aus, um die Änderungen zu speichern." + +#, fuzzy +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "

    Bitte beachten Sie, dass Ihre Email-Adresse als Nutzername verwendet wird. Vergessen Sie nicht, Ihre neue E-Mail-Adresse beim der nächsten Anmeldung zu verwenden, falls Sie diese geändert haben.

    " + +msgid "Please only enter up to 165 characters, you have used" +msgstr "Please only enter up to 165 characters, you have used" + +#, fuzzy +msgid "Please select an organisation, or select Other." +msgstr "Organisation" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "Vorschau" + +#, fuzzy +msgid "Primary research organisation" +msgstr "Organisation" + +msgid "Principal Investigator / Researcher" +msgstr "Principal Investigator / Forscher" + +msgid "Principal Investigator/Researcher" +msgstr "Projektleitung / Principal Investigator" + +msgid "Principal Investigator/Researcher ID" +msgstr "Principal Investigator ID" + +msgid "Private" +msgstr "Private" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "Private (Besitzer, Miteigentümer und Admins) Siehe unsere Nutzungsbedingungen." + +msgid "Privileges" +msgstr "" + +msgid "Project title" +msgstr "" + +#, fuzzy +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "user" + +msgid "Public" +msgstr "Öffentlichkeit" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "Öffentlich im Internet. Ihr DMP erscheint auf der Public DMPs Seite dieser Seite." + +msgid "Public DMPs" +msgstr "Öffentliche DMPs" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "Öffentliche DMPs sind Pläne, die mit dem DMPTool erstellt und öffentlich von ihren Eigentümern veröffentlicht werden. Sie werden nicht auf Qualität, Vollständigkeit oder die Einhaltung der funder Richtlinien überprüft." + +msgid "Publish" +msgstr "" + +msgid "Publish changes" +msgstr "" + +msgid "Published" +msgstr "Veröffentlicht" + +msgid "Question" +msgstr "Frage" + +msgid "Question not answered" +msgstr "Frage nicht beantwortet." + +msgid "Question not answered." +msgstr "Frage nicht beantwortet." + +msgid "Question number" +msgstr "Fragennummer" + +msgid "Question text" +msgstr "Fragentext" + +msgid "Question text is empty, please enter your question." +msgstr "Question text is empty, please enter your question." + +msgid "Questions" +msgstr "Fragen" + +msgid "Radio buttons" +msgstr "Optionsfelder" + +msgid "Read more on the " +msgstr "" + +msgid "Read only" +msgstr "Nur Lesen" + +msgid "Releases" +msgstr "" + +msgid "Remember me" +msgstr "angemeldet bleiben" + +msgid "Remove" +msgstr "Entfernen" + +msgid "Remove user access" +msgstr "Mitarbeitende(n) entfernen" + +msgid "Reset" +msgstr "Zurücksetzen" + +msgid "Right" +msgstr "Rechts" + +msgid "Save" +msgstr "Speichern" + +#, fuzzy +msgid "Save Unsuccessful." +msgstr "Speichern" + +msgid "Saving..." +msgstr "Speichere..." + +msgid "Screencast on how to use %{application_name}" +msgstr "" + +msgid "Section" +msgstr "Abschnitt" + +msgid "Sections" +msgstr "Abschnitte" + +#, fuzzy +msgid "Select a template" +msgstr "templates" + +msgid "Select an action" +msgstr "Wählen Sie eine Aktion" + +#, fuzzy +msgid "Select the funding organisation" +msgstr "Organisation" + +#, fuzzy +msgid "Select the primary research organisation responsible" +msgstr "Organisation" + +msgid "Select which group this guidance relates to." +msgstr "Wählen Sie die Gruppe aus, für die diese Hilfestellung relevant ist." + +msgid "Select which theme(s) this guidance relates to." +msgstr "Wählen Sie die Themen aus, für die diese Hilfestellung relevant ist." + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "Teilen" + +msgid "Share note" +msgstr "Füge Kommentar hinzu" + +msgid "Share note with collaborators" +msgstr "Bitte füge einen Kommentar hinzu" + +msgid "Sharing details successfully updated." +msgstr "" + +msgid "Should this guidance apply:" +msgstr "Soll diese Hilfestellung angewendet werden auf:" + +msgid "Sign in" +msgstr "Anmelden" + +msgid "Sign out" +msgstr "Abmelden" + +msgid "Signed in as " +msgstr "Angemeldet als " + +msgid "Size" +msgstr "Größe" + +#, fuzzy +msgid "Someone has requested a link to change your " +msgstr "Someone has requested a link to change your" + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "Antwortvorschlag" + +msgid "Suggested answer/ Example" +msgstr "Antwortvorschlag / Beispiel" + +msgid "Super admin area" +msgstr "Superadmin" + +msgid "Template" +msgstr "Template" + +msgid "Template History" +msgstr "" + +msgid "Template details" +msgstr "Details der Vorlage" + +msgid "Templates" +msgstr "Vorlagen" + +msgid "Terms of use" +msgstr "Nutzungsbedingungen" + +msgid "Test/Practice" +msgstr "Test/Übung" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "Test / Praxis (Ihr Plan ist für andere Benutzer nicht sichtbar) Siehe unsere Nutzungsbedingungen." + +msgid "Text" +msgstr "Text" + +msgid "Text area" +msgstr "Text area" + +msgid "Text field" +msgstr "Textfeld" + +#, fuzzy +msgid "Thank you for registering. Please confirm your email address" +msgstr "Thank you for registering at %{application_name}. Please confirm your email address:" + +msgid "That email address is already registered." +msgstr "" + +#, fuzzy +msgid "That template is not currently published." +msgstr "templates" + +msgid "The" +msgstr "" + +msgid "The " +msgstr "" + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "Die E-Mail -Adresse des Administrators in Ihrer Org. Ihre Benutzer werden diese Adresse verwenden, wenn sie Fragen haben." + +msgid "The following answer cannot be saved" +msgstr "" + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "Die hier ausgewählten Einträge werden in der Tabelle unten angezeigt. Sie können die Daten durch jeden ihrer Tabellenköpfe sortieren oder filtern, indem Sie eine Zeichenkette in der Suchbox eingeben." + +msgid "Themes" +msgstr "Themen" + +msgid "There are no public DMPs." +msgstr "Es wurden noch keine DMPs veröffentlicht." + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "Es scheint ein Problem mit unserem Logo zu sein. Bitte laden Sie es erneut." + +msgid "These are the basic details for your organisation." +msgstr "Grundlegende Informationen über ihre Org." + +msgid "This allows you to order questions within a section." +msgstr "Hier können sie die Reihenfolge der Fragen innerhalb eines Abschnittes bestimmen." + +msgid "This allows you to order sections." +msgstr "Hier können Sie die Reihenfolge der Abschnitte bestimmen." + +msgid "This allows you to order the phases of your template." +msgstr "Hier können sie die Abfolge der Phasen in Ihrer Vorlage bestimmen." + +msgid "This document was generated by %{application_name}" +msgstr "%{application_name}" + +msgid "This must match what you entered in the previous field." +msgstr "Die Eingabe in diesem Feld muss mit der im vorherigen Feld übereinstimmen." + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "Diese Seite bietet Ihnen einen Überblick über Ihren Plan. Sie gibt an, worauf dieser Plan basiert und gibt eine Übersicht über die Fragen, die gestellt werden." + +#, fuzzy +msgid "This plan is based on the default template." +msgstr "templates" + +msgid "This plan is based on:" +msgstr "Dieser Plan basiert auf:" + +msgid "This section is locked for editing by " +msgstr "Dieser Abschnitt ist gespert wegen Bearbeitung durch " + +msgid "Title" +msgstr "Titel" + +msgid "Top" +msgstr "Oben" + +msgid "Top banner text" +msgstr "" + +msgid "Transfer customisation" +msgstr "" + +#, fuzzy +msgid "Un-published" +msgstr "Veröffentlicht" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "Unbekannter Spaltenname." + +msgid "Unknown formatting setting" +msgstr "Unbekannte Formatierungseinstellung" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "Unbekannter Rand. Kann nur 'oben', 'unten', 'links' oder 'rechts' sein" + +msgid "Unlink account" +msgstr "Trenne Zugang" + +msgid "Unlink institutional credentials alert" +msgstr "Unlink institutional credentials alert" + +msgid "Unlock my account" +msgstr "Unlock my account" + +msgid "Unpublish" +msgstr "" + +#, fuzzy +msgid "Unpublished" +msgstr "Veröffentlicht" + +msgid "Unpublished changes" +msgstr "" + +msgid "Unsaved answers" +msgstr "Ungesicherte Antworten" + +msgid "Unsaved changes" +msgstr "Ungesicherte Änderungen" + +msgid "Upload a new logo file" +msgstr "Laden Sie ein neues Logo-Datei" + +msgid "Users" +msgstr "Nutzer" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "Version" + +msgid "View" +msgstr "Ansicht" + +msgid "View all guidance" +msgstr "Alle Hilfestellungen ansehen" + +msgid "View all templates" +msgstr "Alle Vorlagen ansehen" + +msgid "View phase" +msgstr "Phase ansehen" + +msgid "View plans" +msgstr "Pläne anzeigen" + +msgid "Visibility" +msgstr "Sichtweite" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "templates" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "Organisation" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "templates" + +msgid "Website" +msgstr "Web-Seite" + +#, fuzzy +msgid "Welcome to " +msgstr "Willkommen." + +msgid "Welcome to %{application_name}" +msgstr "Welcome to %{application_name}" + +msgid "Welcome." +msgstr "Willkommen." + +#, fuzzy +msgid "What research project are you planning?" +msgstr "plans" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "Wenn Sie eine neue Phase in einer Vorlage anlegen, wird automatische eine Version erzeugt. Nachdem Sie das folgende Formular ausgefüllt haben, werden Ihnen Optionen zum erstellen von Abschnitten und Fragen angezeigt." + +#, fuzzy +msgid "Which DMP template would you like to use?" +msgstr "templates" + +msgid "Would you like to save them now?" +msgstr "Wollen Sie sie jetzt sichern?" + +msgid "Yes" +msgstr "" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "Sie sind dabei '%{guidance_group_name}' zu löschen. Das wird Auswirkungen auf die Hilfestellungen haben. Sind Sie sicher?" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "Sie sind dabei '%{phase_title}' zu löschen. Das wird Auswirkungen auf die Versionen, Abschnitte und Fragen haben, die mit dieser Phase verknüpft sind. Sind Sie sicher?" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "Sie sind dabei '%{question_text}' zu löschen. Sind Sie sicher?" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "Sie sind dabei '%{section_title}' zu entfernen. Das wird Auswirkungen auf die Fragen haben, die mit diesem Abschnitt verbunden sind. Sind Sie sicher?" + +#, fuzzy +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "Sie sind dabei den Antwortvorschlag / das Beispiel für '%{question_text}' zu löschen. Sind Sie sicher?" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "Sie sind dabei den Antwortvorschlag / das Beispiel für '%{question_text}' zu löschen. Sind Sie sicher?" + +#, fuzzy +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "Sie sind dabei den Antwortvorschlag / das Beispiel für '%{question_text}' zu löschen. Sind Sie sicher?" + +msgid "You are not authorized to perform this action." +msgstr "" + +#, fuzzy +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "templates" + +#, fuzzy +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Hier können Sie einen Text als Beispiel oder Vorschlag angeben, der Nutzern bei der Beantwortung helfen soll. Der Text erscheint oberhalb des Antwortfeldes und kann kopiert und eingefügt werden." + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Hier können Sie einen Text als Beispiel oder Vorschlag angeben, der Nutzern bei der Beantwortung helfen soll. Der Text erscheint oberhalb des Antwortfeldes und kann kopiert und eingefügt werden." + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "Sie haben die Wahl zwischen:
    • - Textbereiche (große Box für Absätze);
    • - Textfelder (für kurze Antworten);
    • - Checkboxen, die Antwortoptionen in Listen präsentieren und eine Mehrfachauswahl ermöglichen
    • - Optionsfelder, die Antwortoptionen in Listen präsentieren, aus der eine ausgewählt wird
    • - Klapplisten, Eingabelisten wie diese - nur eine Option kann ausgewählt
    • - Mehrfachauswahllisten, die Antwortoptionen in einer scrollbaren Liste präsentieren und Merhfachauswahl durch klicken und gleichzeitiges Drücken der Kommando- bzw. Steuerungstaste erlauben
    " + +msgid "You can edit any of the details below." +msgstr "Alle folgenden Angaben können bearbeitet werden." + +msgid "You can not continue until you have filled in all of the required information." +msgstr "" + +#, fuzzy +msgid "You can not edit a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You can not publish a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You cannot delete historical versions of this template." +msgstr "templates" + +msgid "You have altered answers but have not saved them:" +msgstr "Geänderte Antworten wurden nicht gesichert:" + +msgid "You have been given " +msgstr "" + +#, fuzzy +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "Organisation" + +msgid "You have un-published changes" +msgstr "" + +#, fuzzy +msgid "You have unsaved answers in the following sections:" +msgstr "" +"You have unsaved answers in the following sections:\n" + +msgid "You must accept the terms and conditions to register." +msgstr "" + +msgid "You must enter a valid email address." +msgstr "Bitte geben Sie eine gültige E-Mail-Adresse an." + +msgid "You need to sign in or sign up before continuing." +msgstr "Bitte loggen Sie sich ein oder melden Sie sich fortsetzen." + +msgid "You now have " +msgstr "" + +#, fuzzy +msgid "Your" +msgstr "Your " + +msgid "Your ORCID" +msgstr "Ihre ORCID" + +#, fuzzy +msgid "Your access to " +msgstr "Your " + +#, fuzzy +msgid "Your account has been successfully linked to %{scheme}." +msgstr "Your " + +#, fuzzy +msgid "Your account won't be created until you access the link above and set your password." +msgstr "Your " + +msgid "Your browser does not support the video tag." +msgstr "" + +msgid "Your password must contain at least 8 characters." +msgstr "Ihr Passwort muss mindestens acht Zeichen enthalten." + +#, fuzzy +msgid "Your permissions relating to " +msgstr "Your " + +#, fuzzy +msgid "Your template has been published and is now available to users." +msgstr "templates" + +#, fuzzy +msgid "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" +msgstr "templates" + +msgid "a day" +msgstr "" + +msgid "about %d hours" +msgstr "" + +msgid "about a minute" +msgstr "" + +msgid "about a month" +msgstr "" + +msgid "about a year" +msgstr "" + +msgid "about an hour" +msgstr "" + +#, fuzzy +msgid "account has been locked due to an excessive number of unsuccessful sign in attempts." +msgstr " account has been locked due to an excessive number of unsuccessful sign in attempts." + +msgid "activerecord.errors.messages.record_invalid" +msgstr "" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.current_password.invalid" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.email.blank" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.password.blank" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.password_confirmation.confirmation" +msgstr "user" + +msgid "add guidance text" +msgstr "add guidance text" + +# Timeago - found in lib/assets/javascripts/jquery.timeago.js +# --------------------- +# suffix ago +msgid "ago" +msgstr "" + +#, fuzzy +msgid "approx. %{space_used}%% of available space used (max %{num_pages} pages)" +msgstr "annährend %{space_used}% des verfügbaren Platzes wird verwendet (max. %{num_pages} Seiten)" + +#, fuzzy +msgid "by " +msgstr " von " + +msgid "can't be blank" +msgstr "" + +msgid "can't be larger than 500KB" +msgstr "" + +msgid "can't be less than zero" +msgstr "" + +msgid "e.g. School/ Department" +msgstr "z.B. Fakultät / Einrichtung" + +#, fuzzy +msgid "example answer" +msgstr "Beispielantwort" + +msgid "from now" +msgstr "" + +#, fuzzy +msgid "generic template" +msgstr "templates" + +msgid "guidance" +msgstr "" + +#, fuzzy +msgid "guidance group" +msgstr "Hilfestellungsgruppe" + +msgid "guidance on" +msgstr "" + +msgid "height must be less than 100px" +msgstr "" + +msgid "helpers.is_test" +msgstr "" + +msgid "helpers.links.cancel" +msgstr "" + +msgid "helpers.project.is_test_help_text" +msgstr "" + +#, fuzzy +msgid "into your browser" +msgstr "into your browser)." + +msgid "less than a minute" +msgstr "" + +#, fuzzy +msgid "must be logged in" +msgstr "Zuletzt angemeldet" + +msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" +msgstr "" + +msgid "must be unique" +msgstr "" + +#, fuzzy +msgid "must have access to guidances api" +msgstr "guidances" + +#, fuzzy +msgid "must have access to plans api" +msgstr "guidances" + +#, fuzzy +msgid "no research organisation is associated with this plan" +msgstr "Organisation" + +#, fuzzy +msgid "note" +msgstr "Kommentar" + +#, fuzzy +msgid "or copy" +msgstr "(or copy" + +#, fuzzy +msgid "organisation" +msgstr "Organisation" + +#, fuzzy +msgid "phase" +msgstr "Phase" + +#, fuzzy +msgid "plan" +msgstr "plans" + +msgid "profile" +msgstr "" + +#, fuzzy +msgid "question" +msgstr "Frage" + +msgid "questions answered" +msgstr "Fragen beantwortet" + +#, fuzzy +msgid "role" +msgstr "Rolle" + +#, fuzzy +msgid "section" +msgstr "Abschnitt" + +msgid "select a guidance group" +msgstr "select a guidance group" + +msgid "select at least one theme" +msgstr "select at least one theme" + +msgid "since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again." +msgstr "" + +#, fuzzy +msgid "template" +msgstr "templates" + +msgid "user" +msgstr "user" + +#, fuzzy +msgid "user must be in your organisation" +msgstr "Organisation" diff --git a/config/locale/en_GB/app.po b/config/locale/en_GB/app.po new file mode 100644 index 0000000..0d6a6e3 --- /dev/null +++ b/config/locale/en_GB/app.po @@ -0,0 +1,1779 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2017-05-02 14:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr " (UK users only)" + +msgid " - " +msgstr " - " + +#, fuzzy +msgid " I accept the terms and conditions *" +msgstr " I accept the terms and conditions *" + +#, fuzzy +msgid " Plan" +msgstr "plan" + +msgid " access to" +msgstr " access to" + +#, fuzzy +msgid " access. " +msgstr " access to" + +#, fuzzy +msgid " and " +msgstr " on " + +msgid " by" +msgstr " by" + +msgid " by " +msgstr " by " + +msgid " has been removed by " +msgstr " has been removed by " + +#, fuzzy +msgid " have been changed by" +msgstr " by" + +msgid " into your browser)" +msgstr " into your browser)." + +msgid " on " +msgstr " on " + +#, fuzzy +msgid " or " +msgstr " on " + +msgid " password. You can do this through the link below." +msgstr " password. You can do this through the link below." + +#, fuzzy +msgid " provided by " +msgstr " by " + +msgid " team" +msgstr " team" + +#, fuzzy +msgid " that has been customised by " +msgstr " by " + +msgid " to accept the invitation, (or copy " +msgstr " to accept the invitation, (or copy " + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " + +#, fuzzy +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "\"Are you sure you want to unlink your #{scheme.description} ID?\"" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" + +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "\"Your account has been linked to #{scheme.description}.\"" + +msgid "%d days" +msgstr "%d days" + +msgid "%d minutes" +msgstr "%d minutes" + +msgid "%d months" +msgstr "%d months" + +msgid "%d years" +msgstr "%d years" + +msgid "%{application_name}" +msgstr "%{application_name}" + +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." + +#, fuzzy +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "%{application_name}" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." + +msgid "%{value} is not a valid format" +msgstr "%{value} is not a valid format" + +msgid "(Using custom PDF formatting values)" +msgstr "(Using custom PDF formatting values)" + +msgid "(Using template PDF formatting values)" +msgstr "(Using template PDF formatting values)" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "... (continued)" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " + +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "

    %{application_name} stories from the %{organisation_abbreviation} website


    " + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "

    Here you can view previously published versions of your template. These can no longer be modified.

    " + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " + +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " + +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " + +#, fuzzy +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "%{application_name}" + +#, fuzzy +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "%{application_name}" + +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "A colleague has invited you to contribute to their Data Management Plan at " + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "A pertinent ID as determined by the funder and/or institution." + +msgid "A required setting has not been provided" +msgstr "A required setting has not been provided" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "API Information" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "API token" + +msgid "Abbreviation" +msgstr "Abbreviation" + +msgid "About" +msgstr "About" + +msgid "About %{application_name}" +msgstr "About %{application_name}" + +msgid "Access removed" +msgstr "Access removed" + +msgid "Actions" +msgstr "Actions" + +msgid "Add Annotations" +msgstr "" + +#, fuzzy +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "guidance group" + +msgid "Add collaborator" +msgstr "Add collaborator" + +msgid "Add guidance" +msgstr "Add guidance" + +msgid "Add guidance group" +msgstr "Add guidance group" + +msgid "Add new phase +" +msgstr "Add new phase +" + +msgid "Add note" +msgstr "Add note" + +msgid "Add option" +msgstr "Add option" + +msgid "Add question" +msgstr "Add question" + +msgid "Add section" +msgstr "Add section" + +msgid "Additional comment area will be displayed." +msgstr "Additional comment area will be displayed." + +msgid "Admin Details" +msgstr "Admin Details" + +msgid "Admin area" +msgstr "Admin area" + +msgid "All the best," +msgstr "" + +#, fuzzy +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "organisation" + +#, fuzzy +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "organisation" + +#, fuzzy +msgid "Allows the user to create and edit guidance" +msgstr "guidance" + +#, fuzzy +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "template" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +msgid "Answer" +msgstr "Answer" + +msgid "Answer format" +msgstr "Answer format" + +msgid "Answer questions" +msgstr "Answer questions" + +msgid "Answered" +msgstr "Answered" + +msgid "Answered at" +msgstr "Answered at" + +msgid "Answered by" +msgstr "Answered by" + +msgid "Answers" +msgstr "Answers" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." + +msgid "Are you sure you want to remove this note?" +msgstr "Are you sure you want to remove this note?" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" + +msgid "Are you sure?" +msgstr "Are you sure?" + +msgid "Back" +msgstr "Back" + +msgid "Back to edit view" +msgstr "Back to edit view" + +msgid "Background" +msgstr "Background" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "Before submitting, please consider:" + +#, fuzzy +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "questions" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "Below is a list of users registered for your organisation. You can sort the data by each field." + +msgid "Bottom" +msgstr "Bottom" + +msgid "By " +msgstr "By " + +msgid "Cancel" +msgstr "Cancel" + +#, fuzzy +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "plan" + +msgid "Change language" +msgstr "Change language" + +msgid "Change my password" +msgstr "Change my password" + +#, fuzzy +msgid "Change organisation details" +msgstr "organisation" + +msgid "Check box" +msgstr "Check box" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "Check this box when you are ready for this guidance to appear on user's plans." + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "Click here to accept the invitation" + +msgid "Click here to confirm your account" +msgstr "Click here to confirm your account" + +msgid "Click the link below to unlock your account" +msgstr "Click the link below to unlock your account" + +msgid "Co-owner" +msgstr "Co-owner" + +msgid "Collaborators" +msgstr "Collaborators" + +msgid "Comment" +msgstr "Comment" + +msgid "Comment removed." +msgstr "Comment removed." + +msgid "Comment was successfully created." +msgstr "Comment was successfully created." + +msgid "Comment was successfully saved." +msgstr "Comment was successfully saved." + +msgid "Contact Email" +msgstr "Contact Email" + +#, fuzzy +msgid "Contact Us" +msgstr "Contact us" + +msgid "Contact us" +msgstr "Contact us" + +msgid "Create a new plan" +msgstr "Create a new plan" + +msgid "Create a template" +msgstr "Create a template" + +msgid "Create account" +msgstr "Create account" + +msgid "Create plan" +msgstr "Create plan" + +msgid "Created" +msgstr "Created" + +msgid "Created at" +msgstr "Created at" + +msgid "Current password" +msgstr "Current password" + +msgid "Customise" +msgstr "Customise" + +msgid "Default" +msgstr "Default" + +msgid "Default answer" +msgstr "Default answer" + +msgid "Default value" +msgstr "Default value" + +msgid "Delete" +msgstr "Delete" + +#, fuzzy +msgid "Delete Example Answer" +msgstr "Example of answer" + +msgid "Delete question" +msgstr "Delete question" + +msgid "Description" +msgstr "Description" + +msgid "Details" +msgstr "Details" + +msgid "Details successfully updated." +msgstr "Details successfully updated." + +msgid "Didn't receive confirmation instructions?" +msgstr "Didn't receive confirmation instructions?" + +msgid "Didn't receive unlock instructions?" +msgstr "Didn't receive unlock instructions?" + +msgid "Discard" +msgstr "Discard" + +msgid "Display additional comment area." +msgstr "Display additional comment area." + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "Dropdown" + +msgid "E.g ORCID http://orcid.org/." +msgstr "E.g ORCID http://orcid.org/." + +msgid "Edit" +msgstr "Edit" + +#, fuzzy +msgid "Edit Annotations" +msgstr "Edit" + +msgid "Edit User Privileges" +msgstr "Edit User Privileges" + +msgid "Edit customisation" +msgstr "Edit customisation" + +msgid "Edit phase" +msgstr "Edit phase" + +msgid "Edit phase details" +msgstr "Edit phase details" + +msgid "Edit plan details" +msgstr "Edit plan details" + +msgid "Edit profile" +msgstr "Edit profile" + +msgid "Edit question" +msgstr "Edit question" + +msgid "Edit template details" +msgstr "Edit template details" + +msgid "Editor" +msgstr "Editor" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." + +msgid "Email" +msgstr "Email" + +msgid "Email address" +msgstr "Email address" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." + +msgid "Enter your guidance here. You can include links where needed." +msgstr "Enter your guidance here. You can include links where needed." + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." + +msgid "Error!" +msgstr "Error!" + +#, fuzzy +msgid "Example Answer" +msgstr "Example of answer" + +#, fuzzy +msgid "Example of answer" +msgstr "Example of answer" + +msgid "Export" +msgstr "Export" + +msgid "Export settings updated successfully." +msgstr "Export settings updated successfully." + +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "Exporting public plan is under development. Apologies for any inconvience." + +msgid "Face" +msgstr "Face" + +msgid "File Name" +msgstr "File Name" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "Filter plans" + +msgid "First name" +msgstr "First name" + +msgid "Font" +msgstr "Font" + +msgid "Forgot your password?" +msgstr "Forgot your password?" + +#, fuzzy +msgid "Format" +msgstr "format" + +msgid "Funder" +msgstr "Funder" + +msgid "Funders templates" +msgstr "Funders templates" + +#, fuzzy +msgid "Funding organisation" +msgstr "organisation" + +msgid "Future plans" +msgstr "Future plans" + +msgid "Get involved" +msgstr "Get involved" + +msgid "Grant number" +msgstr "Grant number" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "Grant reference number if applicable [POST-AWARD DMPs ONLY]" + +msgid "Guidance" +msgstr "Guidance" + +#, fuzzy +msgid "Guidance choices saved." +msgstr "Guidance" + +msgid "Guidance group" +msgstr "Guidance group" + +msgid "Guidance group list" +msgstr "Guidance group list" + +msgid "Guidance group was successfully created." +msgstr "Guidance group was successfully created." + +msgid "Guidance group was successfully deleted." +msgstr "Guidance group was successfully deleted." + +msgid "Guidance group was successfully updated." +msgstr "Guidance group was successfully updated." + +msgid "Guidance list" +msgstr "Guidance list" + +msgid "Guidance was successfully created." +msgstr "Guidance was successfully created." + +msgid "Guidance was successfully deleted." +msgstr "Guidance was successfully deleted." + +msgid "Guidance was successfully updated." +msgstr "Guidance was successfully updated." + +msgid "Hello" +msgstr "Hello" + +msgid "Hello " +msgstr "Hello " + +msgid "Help" +msgstr "Help" + +msgid "History" +msgstr "History" + +msgid "Home" +msgstr "Home" + +msgid "How many plans?" +msgstr "How many plans?" + +msgid "How to use the API" +msgstr "How to use the API" + +msgid "ID" +msgstr "ID" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "If applying for funding, state the name exactly as in the grant proposal." + +#, fuzzy +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "If applying for funding, state the name exactly as in the grant proposal." + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "If you would like to change your password please complete the following fields." + +msgid "Included Elements" +msgstr "Included Elements" + +msgid "Information was successfully created." +msgstr "Information was successfully created." + +msgid "Information was successfully deleted." +msgstr "Information was successfully deleted." + +msgid "Information was successfully updated." +msgstr "Information was successfully updated." + +msgid "Institution" +msgstr "Institution" + +msgid "Invalid font face" +msgstr "Invalid font face" + +msgid "Invalid font size" +msgstr "Invalid font size" + +msgid "Invalid maximum pages" +msgstr "Invalid maximum pages" + +#, fuzzy +msgid "Invitation to %{email} issued successfully." +msgstr "Invitation issued successfully." + +msgid "Language" +msgstr "Language" + +msgid "Last logged in" +msgstr "Last logged in" + +msgid "Last name" +msgstr "Last name" + +msgid "Last updated" +msgstr "Last updated" + +msgid "Latest news" +msgstr "Latest news" + +msgid "Left" +msgstr "Left" + +msgid "List of users" +msgstr "List of users" + +msgid "Logo" +msgstr "Logo" + +msgid "Main organisation" +msgstr "Main organisation" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "Margin" + +msgid "Margin cannot be negative" +msgstr "Margin cannot be negative" + +msgid "Margin value is invalid" +msgstr "Margin value is invalid" + +msgid "Me" +msgstr "Me" + +#, fuzzy +msgid "Message" +msgstr "Me" + +#, fuzzy +msgid "Modify guidance" +msgstr "guidance" + +#, fuzzy +msgid "Modify templates" +msgstr "template" + +msgid "Multi select box" +msgstr "Multi select box" + +#, fuzzy +msgid "My Plan" +msgstr "My plan" + +msgid "My organisation isn't listed." +msgstr "My organisation isn't listed." + +msgid "My plans" +msgstr "My plans" + +#, fuzzy +msgid "My research organisation is not on the list" +msgstr "organisation" + +msgid "Name" +msgstr "Name" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "Name (if different to above), telephone and email contact details" + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "Name of Principal Investigator(s) or main researcher(s) on the project." + +msgid "New guidance" +msgstr "New guidance" + +msgid "New password" +msgstr "New password" + +msgid "New section title" +msgstr "New section title" + +msgid "New template" +msgstr "New template" + +msgid "New to %{application_name}? Create an account today." +msgstr "New to %{application_name}? Create an account today." + +msgid "No" +msgstr "No" + +msgid "No additional comment area will be displayed." +msgstr "No additional comment area will be displayed." + +#, fuzzy +msgid "No funder associated with this plan" +msgstr "plan" + +#, fuzzy +msgid "No items available." +msgstr "No" + +msgid "No matches" +msgstr "No matches" + +msgid "None" +msgstr "None" + +msgid "Not answered yet" +msgstr "Not answered yet" + +msgid "Note" +msgstr "Note" + +msgid "Note removed by" +msgstr "Note removed by" + +msgid "Note removed by you" +msgstr "Note removed by you" + +msgid "Noted by:" +msgstr "Noted by:" + +msgid "Ok" +msgstr "Ok" + +msgid "On %{application_name}" +msgstr "On %{application_name}" + +msgid "On data management planning" +msgstr "On data management planning" + +msgid "Optional subset" +msgstr "Optional subset" + +msgid "Or, sign in with your institutional credentials" +msgstr "Or, sign in with your institutional credentials" + +msgid "Order" +msgstr "Order" + +msgid "Order of display" +msgstr "Order of display" + +msgid "Organisation" +msgstr "Organisation" + +msgid "Organisation details" +msgstr "Organisation details" + +msgid "Organisation name" +msgstr "Organisation name" + +msgid "Organisation type" +msgstr "Organisation type" + +msgid "Organisation was successfully updated." +msgstr "Organisation was successfully updated." + +msgid "Organisational" +msgstr "Organisational" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "Organisational (visibile to others within your organisation)" + +msgid "Organization" +msgstr "Organisation" + +msgid "Original funder template has changed!" +msgstr "Original funder template has changed!" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "Own templates" + +msgid "Owner" +msgstr "Owner" + +msgid "PDF Formatting" +msgstr "PDF Formatting" + +msgid "Password" +msgstr "Password" + +msgid "Password and comfirmation must match" +msgstr "Password and confirmation must match" + +msgid "Password confirmation" +msgstr "Password confirmation" + +msgid "Permissions" +msgstr "Permissions" + +msgid "Phase details" +msgstr "Phase details" + +msgid "Plan Data Contact" +msgstr "Plan Data Contact" + +msgid "Plan Description" +msgstr "Plan Description" + +msgid "Plan ID" +msgstr "Plan ID" + +msgid "Plan Name" +msgstr "Plan Name" + +msgid "Plan data contact" +msgstr "Plan data contact" + +msgid "Plan details" +msgstr "Plan details" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "Plan name" + +msgid "Plan shared with %{email}." +msgstr "" + +msgid "Plan was successfully deleted." +msgstr "Plan was successfully deleted." + +msgid "Plan was successfully updated." +msgstr "Plan was successfully updated." + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +#, fuzzy +msgid "Please enter a First name." +msgstr "Please enter your first name." + +#, fuzzy +msgid "Please enter a Last name." +msgstr "Please enter your first name." + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "Please enter a title for your template." + +msgid "Please enter a valid web address." +msgstr "Please enter a valid web address." + +msgid "Please enter an email address" +msgstr "Please enter an email address" + +#, fuzzy +msgid "Please enter an email address." +msgstr "Please enter an email address" + +msgid "Please enter the name of your organisation." +msgstr "Please enter the name of your organisation." + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "Please enter your first name." + +msgid "Please enter your organisation's name." +msgstr "Please enter your organisation's name." + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "Please enter your surname or family name." + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "Please fill in the basic project details below and click 'Update' to save" + +#, fuzzy +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "

    Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in.

    " + +msgid "Please only enter up to 165 characters, you have used" +msgstr "Please only enter up to 165 characters, you have used" + +#, fuzzy +msgid "Please select an organisation, or select Other." +msgstr "organisation" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "Preview" + +#, fuzzy +msgid "Primary research organisation" +msgstr "organisation" + +msgid "Principal Investigator / Researcher" +msgstr "Principal Investigator / Researcher" + +msgid "Principal Investigator/Researcher" +msgstr "Principal Investigator/Researcher" + +msgid "Principal Investigator/Researcher ID" +msgstr "Principal Investigator/Researcher ID" + +msgid "Private" +msgstr "Private" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "Private (owners, co-owners, and administrators only) See our Terms of Use." + +msgid "Privileges" +msgstr "Privileges" + +msgid "Project title" +msgstr "" + +#, fuzzy +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "API token" + +msgid "Public" +msgstr "Public" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "Public (Your DMP will appear on the Public DMPs page of this site)" + +msgid "Public DMPs" +msgstr "Public DMPs" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." + +msgid "Publish" +msgstr "Publish" + +msgid "Publish changes" +msgstr "Publish changes" + +msgid "Published" +msgstr "Published" + +msgid "Question" +msgstr "Question" + +msgid "Question not answered" +msgstr "Question not answered." + +msgid "Question not answered." +msgstr "Question not answered." + +msgid "Question number" +msgstr "Question number" + +msgid "Question text" +msgstr "Question text" + +msgid "Question text is empty, please enter your question." +msgstr "Question text is empty, please enter your question." + +msgid "Questions" +msgstr "Questions" + +msgid "Radio buttons" +msgstr "Radio buttons" + +msgid "Read more on the " +msgstr "Read more on the " + +msgid "Read only" +msgstr "Read only" + +msgid "Releases" +msgstr "Releases" + +msgid "Remember me" +msgstr "Remember me" + +msgid "Remove" +msgstr "Remove" + +msgid "Remove user access" +msgstr "Remove user access" + +msgid "Reset" +msgstr "Reset" + +msgid "Right" +msgstr "Right" + +msgid "Save" +msgstr "Save" + +#, fuzzy +msgid "Save Unsuccessful." +msgstr "Save" + +msgid "Saving..." +msgstr "Saving..." + +msgid "Screencast on how to use %{application_name}" +msgstr "Screencast on how to use %{application_name}" + +msgid "Section" +msgstr "Section" + +msgid "Sections" +msgstr "Sections" + +#, fuzzy +msgid "Select a template" +msgstr "template" + +msgid "Select an action" +msgstr "Select an action" + +#, fuzzy +msgid "Select the funding organisation" +msgstr "organisation" + +#, fuzzy +msgid "Select the primary research organisation responsible" +msgstr "organisation" + +msgid "Select which group this guidance relates to." +msgstr "Select which group this guidance relates to." + +msgid "Select which theme(s) this guidance relates to." +msgstr "Select which theme(s) this guidance relates to." + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "Share" + +msgid "Share note" +msgstr "Share note" + +msgid "Share note with collaborators" +msgstr "Share note with collaborators" + +msgid "Sharing details successfully updated." +msgstr "Sharing details successfully updated." + +msgid "Should this guidance apply:" +msgstr "Should this guidance apply:" + +msgid "Sign in" +msgstr "Sign in" + +msgid "Sign out" +msgstr "Sign out" + +msgid "Signed in as " +msgstr "Signed in as " + +msgid "Size" +msgstr "Size" + +msgid "Someone has requested a link to change your " +msgstr "Someone has requested a link to change your " + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "Suggested answer" + +msgid "Suggested answer/ Example" +msgstr "Suggested answer/ Example" + +msgid "Super admin area" +msgstr "Super admin area" + +msgid "Template" +msgstr "Template" + +msgid "Template History" +msgstr "Template History" + +msgid "Template details" +msgstr "Template details" + +msgid "Templates" +msgstr "Templates" + +msgid "Terms of use" +msgstr "Terms of use" + +msgid "Test/Practice" +msgstr "Test/Practice" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "Test/Practice (your plan is not visible to other users) See our Terms of Use." + +msgid "Text" +msgstr "Text" + +msgid "Text area" +msgstr "Text area" + +msgid "Text field" +msgstr "Text field" + +msgid "Thank you for registering. Please confirm your email address" +msgstr "Thank you for registering. Please confirm your email address" + +msgid "That email address is already registered." +msgstr "That email address is already registered." + +msgid "That template is not currently published." +msgstr "That template is not currently published." + +#, fuzzy +msgid "The" +msgstr "The " + +msgid "The " +msgstr "The " + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "The email address of an administrator at your organisation. Your users will use this address if they have questions." + +#, fuzzy +msgid "The following answer cannot be saved" +msgstr "The " + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." + +msgid "Themes" +msgstr "Themes" + +msgid "There are no public DMPs." +msgstr "There are no public DMPs." + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "There seems to be a problem with your logo. Please upload it again." + +msgid "These are the basic details for your organisation." +msgstr "These are the basic details for your organisation." + +msgid "This allows you to order questions within a section." +msgstr "This allows you to order questions within a section." + +msgid "This allows you to order sections." +msgstr "This allows you to order sections." + +msgid "This allows you to order the phases of your template." +msgstr "This allows you to order the phases of your template." + +msgid "This document was generated by %{application_name}" +msgstr "This document was generated by %{application_name}" + +msgid "This must match what you entered in the previous field." +msgstr "This must match what you entered in the previous field." + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." + +#, fuzzy +msgid "This plan is based on the default template." +msgstr "template" + +msgid "This plan is based on:" +msgstr "This plan is based on:" + +msgid "This section is locked for editing by " +msgstr "This section is locked for editing by " + +msgid "Title" +msgstr "Title" + +msgid "Top" +msgstr "Top" + +msgid "Top banner text" +msgstr "Top banner text" + +msgid "Transfer customisation" +msgstr "" + +msgid "Un-published" +msgstr "Un-published" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "Unknown column name." + +msgid "Unknown formatting setting" +msgstr "Unknown formatting setting" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" + +msgid "Unlink account" +msgstr "Unlink account" + +msgid "Unlink institutional credentials alert" +msgstr "Unlink institutional credentials alert" + +msgid "Unlock my account" +msgstr "Unlock my account" + +msgid "Unpublish" +msgstr "Unpublish" + +msgid "Unpublished" +msgstr "Unpublished" + +msgid "Unpublished changes" +msgstr "Unpublished changes" + +msgid "Unsaved answers" +msgstr "Unsaved answers" + +msgid "Unsaved changes" +msgstr "Unsaved changes" + +msgid "Upload a new logo file" +msgstr "Upload a new logo file" + +msgid "Users" +msgstr "Users" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "Version" + +msgid "View" +msgstr "View" + +msgid "View all guidance" +msgstr "View all guidance" + +msgid "View all templates" +msgstr "View all templates" + +msgid "View phase" +msgstr "View phase" + +msgid "View plans" +msgstr "View plans" + +msgid "Visibility" +msgstr "Visibility" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "template" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "organisation" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "template" + +msgid "Website" +msgstr "Website" + +msgid "Welcome to " +msgstr "Welcome to " + +msgid "Welcome to %{application_name}" +msgstr "Welcome to %{application_name}" + +msgid "Welcome." +msgstr "Welcome." + +#, fuzzy +msgid "What research project are you planning?" +msgstr "plan" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." + +#, fuzzy +msgid "Which DMP template would you like to use?" +msgstr "template" + +msgid "Would you like to save them now?" +msgstr "Would you like to save them now?" + +msgid "Yes" +msgstr "Yes" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "You are about to delete '%{guidance_summary}'. Are you sure?" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "You are about to delete '%{question_text}'. Are you sure?" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" + +#, fuzzy +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +#, fuzzy +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +msgid "You are not authorized to perform this action." +msgstr "" + +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "You are viewing a historical version of this template. You will not be able to make changes." + +#, fuzzy +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " + +msgid "You can edit any of the details below." +msgstr "You can edit any of the details below." + +#, fuzzy +msgid "You can not continue until you have filled in all of the required information." +msgstr "format" + +msgid "You can not edit a historical version of this template." +msgstr "" + +msgid "You can not publish a historical version of this template." +msgstr "" + +msgid "You cannot delete historical versions of this template." +msgstr "" + +msgid "You have altered answers but have not saved them:" +msgstr "You have altered answers but have not saved them:" + +msgid "You have been given " +msgstr "You have been given " + +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "" + +msgid "You have un-published changes" +msgstr "" + +msgid "You have unsaved answers in the following sections:" +msgstr "" + +msgid "You must accept the terms and conditions to register." +msgstr "You must accept the terms and conditions to register." + +msgid "You must enter a valid email address." +msgstr "You must enter a valid email address." + +msgid "You need to sign in or sign up before continuing." +msgstr "You need to sign in or sign up before continuing." + +msgid "You now have " +msgstr "" + +msgid "Your" +msgstr "Your" + +msgid "Your ORCID" +msgstr "Your ORCID" + +msgid "Your access to " +msgstr "Your access to " + +msgid "Your account has been successfully linked to %{scheme}." +msgstr "Your account has been successfully linked to %{scheme}." + +msgid "Your account won't be created until you access the link above and set your password." +msgstr "Your account won't be created until you access the link above and set your password." + +msgid "Your browser does not support the video tag." +msgstr "Your browser does not support the video tag." + +msgid "Your password must contain at least 8 characters." +msgstr "Your password must contain at least 8 characters." + +msgid "Your permissions relating to " +msgstr "Your permissions relating to " + +msgid "Your template has been published and is now available to users." +msgstr "Your template has been published and is now available to users." + +msgid "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" +msgstr "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" + +msgid "a day" +msgstr "a day" + +msgid "about %d hours" +msgstr "about %d hours" + +msgid "about a minute" +msgstr "about a minute" + +msgid "about a month" +msgstr "about a month" + +msgid "about a year" +msgstr "about a year" + +msgid "about an hour" +msgstr "about an hour" + +msgid "account has been locked due to an excessive number of unsuccessful sign in attempts." +msgstr "account has been locked due to an excessive number of unsuccessful sign in attempts." + +msgid "activerecord.errors.messages.record_invalid" +msgstr "unable to save your changes" + +msgid "activerecord.errors.models.user.attributes.current_password.invalid" +msgstr "invalid email and/or password" + +msgid "activerecord.errors.models.user.attributes.email.blank" +msgstr "can't be blank" + +msgid "activerecord.errors.models.user.attributes.password.blank" +msgstr "can't be blank" + +msgid "activerecord.errors.models.user.attributes.password_confirmation.confirmation" +msgstr "passwords must match" + +msgid "add guidance text" +msgstr "add guidance text" + +# Timeago - found in lib/assets/javascripts/jquery.timeago.js +# --------------------- +# suffix ago +msgid "ago" +msgstr "ago" + +msgid "approx. %{space_used}%% of available space used (max %{num_pages} pages)" +msgstr "approx. %{space_used}%% of available space used (max %{num_pages} pages)" + +#, fuzzy +msgid "by " +msgstr " by " + +msgid "can't be blank" +msgstr "" + +msgid "can't be larger than 500KB" +msgstr "" + +msgid "can't be less than zero" +msgstr "" + +msgid "e.g. School/ Department" +msgstr "e.g. School/ Department" + +#, fuzzy +msgid "example answer" +msgstr "Example of answer" + +msgid "from now" +msgstr "from now" + +#, fuzzy +msgid "generic template" +msgstr "template" + +msgid "guidance" +msgstr "guidance" + +msgid "guidance group" +msgstr "guidance group" + +msgid "guidance on" +msgstr "guidance on" + +msgid "height must be less than 100px" +msgstr "" + +msgid "helpers.is_test" +msgstr "" + +msgid "helpers.links.cancel" +msgstr "" + +msgid "helpers.project.is_test_help_text" +msgstr "" + +msgid "into your browser" +msgstr "into your browser" + +msgid "less than a minute" +msgstr "less than a minute" + +msgid "must be logged in" +msgstr "must be logged in" + +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" + +msgid "must be unique" +msgstr "" + +msgid "must have access to guidances api" +msgstr "must have access to guidances api" + +#, fuzzy +msgid "must have access to plans api" +msgstr "must have access to guidances api" + +#, fuzzy +msgid "no research organisation is associated with this plan" +msgstr "organisation" + +msgid "note" +msgstr "note" + +msgid "or copy" +msgstr "or copy" + +msgid "organisation" +msgstr "organisation" + +msgid "phase" +msgstr "phase" + +msgid "plan" +msgstr "plan" + +msgid "profile" +msgstr "" + +msgid "question" +msgstr "question" + +msgid "questions answered" +msgstr "questions answered" + +msgid "role" +msgstr "role" + +msgid "section" +msgstr "section" + +msgid "select a guidance group" +msgstr "select a guidance group" + +msgid "select at least one theme" +msgstr "select at least one theme" + +#, fuzzy +msgid "since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again." +msgstr " on " + +msgid "template" +msgstr "template" + +msgid "user" +msgstr "user" + +#, fuzzy +msgid "user must be in your organisation" +msgstr "organisation" diff --git a/config/locale/en_US/app.po b/config/locale/en_US/app.po new file mode 100644 index 0000000..d1e5e4e --- /dev/null +++ b/config/locale/en_US/app.po @@ -0,0 +1,1779 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2017-05-02 14:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr " (UK users only)" + +msgid " - " +msgstr " - " + +#, fuzzy +msgid " I accept the terms and conditions *" +msgstr " I accept the terms and conditions *" + +#, fuzzy +msgid " Plan" +msgstr "plan" + +msgid " access to" +msgstr " access to" + +#, fuzzy +msgid " access. " +msgstr " access to" + +#, fuzzy +msgid " and " +msgstr " on " + +msgid " by" +msgstr " by" + +msgid " by " +msgstr " by " + +msgid " has been removed by " +msgstr " has been removed by " + +#, fuzzy +msgid " have been changed by" +msgstr " by" + +msgid " into your browser)" +msgstr " into your browser)." + +msgid " on " +msgstr " on " + +#, fuzzy +msgid " or " +msgstr " on " + +msgid " password. You can do this through the link below." +msgstr " password. You can do this through the link below." + +#, fuzzy +msgid " provided by " +msgstr " by " + +msgid " team" +msgstr " team" + +#, fuzzy +msgid " that has been customised by " +msgstr " by " + +msgid " to accept the invitation, (or copy " +msgstr " to accept the invitation, (or copy " + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " + +#, fuzzy +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "\"Are you sure you want to unlink your #{scheme.description} ID?\"" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" + +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "\"Your account has been linked to #{scheme.description}.\"" + +msgid "%d days" +msgstr "%d days" + +msgid "%d minutes" +msgstr "%d minutes" + +msgid "%d months" +msgstr "%d months" + +msgid "%d years" +msgstr "%d years" + +msgid "%{application_name}" +msgstr "%{application_name}" + +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." + +#, fuzzy +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "%{application_name}" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." + +msgid "%{value} is not a valid format" +msgstr "%{value} is not a valid format" + +msgid "(Using custom PDF formatting values)" +msgstr "(Using custom PDF formatting values)" + +msgid "(Using template PDF formatting values)" +msgstr "(Using template PDF formatting values)" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "... (continued)" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organization and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " + +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "

    %{application_name} stories from the %{organisation_abbreviation} website


    " + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "

    Here you can view previously published versions of your template. These can no longer be modified.

    " + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " + +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " + +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " + +#, fuzzy +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "%{application_name}" + +#, fuzzy +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "%{application_name}" + +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "A colleague has invited you to contribute to their Data Management Plan at " + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "A pertinent ID as determined by the funder and/or institution." + +msgid "A required setting has not been provided" +msgstr "A required setting has not been provided" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "API Information" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "API token" + +msgid "Abbreviation" +msgstr "Abbreviation" + +msgid "About" +msgstr "About" + +msgid "About %{application_name}" +msgstr "About %{application_name}" + +msgid "Access removed" +msgstr "Access removed" + +msgid "Actions" +msgstr "Actions" + +msgid "Add Annotations" +msgstr "" + +#, fuzzy +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "guidance group" + +msgid "Add collaborator" +msgstr "Add collaborator" + +msgid "Add guidance" +msgstr "Add guidance" + +msgid "Add guidance group" +msgstr "Add guidance group" + +msgid "Add new phase +" +msgstr "Add new phase +" + +msgid "Add note" +msgstr "Add note" + +msgid "Add option" +msgstr "Add option" + +msgid "Add question" +msgstr "Add question" + +msgid "Add section" +msgstr "Add section" + +msgid "Additional comment area will be displayed." +msgstr "Additional comment area will be displayed." + +msgid "Admin Details" +msgstr "Admin Details" + +msgid "Admin area" +msgstr "Admin area" + +msgid "All the best," +msgstr "" + +#, fuzzy +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "organization" + +#, fuzzy +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "organization" + +#, fuzzy +msgid "Allows the user to create and edit guidance" +msgstr "guidance" + +#, fuzzy +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "template" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +msgid "Answer" +msgstr "Answer" + +msgid "Answer format" +msgstr "Answer format" + +msgid "Answer questions" +msgstr "Answer questions" + +msgid "Answered" +msgstr "Answered" + +msgid "Answered at" +msgstr "Answered at" + +msgid "Answered by" +msgstr "Answered by" + +msgid "Answers" +msgstr "Answers" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." + +msgid "Are you sure you want to remove this note?" +msgstr "Are you sure you want to remove this note?" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" + +msgid "Are you sure?" +msgstr "Are you sure?" + +msgid "Back" +msgstr "Back" + +msgid "Back to edit view" +msgstr "Back to edit view" + +msgid "Background" +msgstr "Background" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "Before submitting, please consider:" + +#, fuzzy +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "questions" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "Below is a list of users registered for your organization. You can sort the data by each field." + +msgid "Bottom" +msgstr "Bottom" + +msgid "By " +msgstr "By " + +msgid "Cancel" +msgstr "Cancel" + +#, fuzzy +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "plan" + +msgid "Change language" +msgstr "Change language" + +msgid "Change my password" +msgstr "Change my password" + +#, fuzzy +msgid "Change organisation details" +msgstr "organization" + +msgid "Check box" +msgstr "Check box" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "Check this box when you are ready for this guidance to appear on user's plans." + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "Click here to accept the invitation" + +msgid "Click here to confirm your account" +msgstr "Click here to confirm your account" + +msgid "Click the link below to unlock your account" +msgstr "Click the link below to unlock your account" + +msgid "Co-owner" +msgstr "Co-owner" + +msgid "Collaborators" +msgstr "Collaborators" + +msgid "Comment" +msgstr "Comment" + +msgid "Comment removed." +msgstr "Comment removed." + +msgid "Comment was successfully created." +msgstr "Comment was successfully created." + +msgid "Comment was successfully saved." +msgstr "Comment was successfully saved." + +msgid "Contact Email" +msgstr "Contact Email" + +#, fuzzy +msgid "Contact Us" +msgstr "Contact us" + +msgid "Contact us" +msgstr "Contact us" + +msgid "Create a new plan" +msgstr "Create a new plan" + +msgid "Create a template" +msgstr "Create a template" + +msgid "Create account" +msgstr "Create account" + +msgid "Create plan" +msgstr "Create plan" + +msgid "Created" +msgstr "Created" + +msgid "Created at" +msgstr "Created at" + +msgid "Current password" +msgstr "Current password" + +msgid "Customise" +msgstr "Customise" + +msgid "Default" +msgstr "Default" + +msgid "Default answer" +msgstr "Default answer" + +msgid "Default value" +msgstr "Default value" + +msgid "Delete" +msgstr "Delete" + +#, fuzzy +msgid "Delete Example Answer" +msgstr "Example of answer" + +msgid "Delete question" +msgstr "Delete question" + +msgid "Description" +msgstr "Description" + +msgid "Details" +msgstr "Details" + +msgid "Details successfully updated." +msgstr "Details successfully updated." + +msgid "Didn't receive confirmation instructions?" +msgstr "Didn't receive confirmation instructions?" + +msgid "Didn't receive unlock instructions?" +msgstr "Didn't receive unlock instructions?" + +msgid "Discard" +msgstr "Discard" + +msgid "Display additional comment area." +msgstr "Display additional comment area." + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "Dropdown" + +msgid "E.g ORCID http://orcid.org/." +msgstr "E.g ORCID http://orcid.org/." + +msgid "Edit" +msgstr "Edit" + +#, fuzzy +msgid "Edit Annotations" +msgstr "Edit" + +msgid "Edit User Privileges" +msgstr "Edit User Permissions" + +msgid "Edit customisation" +msgstr "Edit customisation" + +msgid "Edit phase" +msgstr "Edit phase" + +msgid "Edit phase details" +msgstr "Edit phase details" + +msgid "Edit plan details" +msgstr "Edit plan details" + +msgid "Edit profile" +msgstr "Edit profile" + +msgid "Edit question" +msgstr "Edit question" + +msgid "Edit template details" +msgstr "Edit template details" + +msgid "Editor" +msgstr "Editor" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." + +msgid "Email" +msgstr "Email" + +msgid "Email address" +msgstr "Email address" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." + +msgid "Enter your guidance here. You can include links where needed." +msgstr "Enter your guidance here. You can include links where needed." + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." + +msgid "Error!" +msgstr "Error!" + +#, fuzzy +msgid "Example Answer" +msgstr "Example of answer" + +#, fuzzy +msgid "Example of answer" +msgstr "Example of answer" + +msgid "Export" +msgstr "Export" + +msgid "Export settings updated successfully." +msgstr "Export settings updated successfully." + +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "Exporting public plan is under development. Apologies for any inconvience." + +msgid "Face" +msgstr "Face" + +msgid "File Name" +msgstr "File Name" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "Filter plans" + +msgid "First name" +msgstr "First name" + +msgid "Font" +msgstr "Font" + +msgid "Forgot your password?" +msgstr "Forgot your password?" + +#, fuzzy +msgid "Format" +msgstr "format" + +msgid "Funder" +msgstr "Funder" + +msgid "Funders templates" +msgstr "Funders templates" + +#, fuzzy +msgid "Funding organisation" +msgstr "organization" + +msgid "Future plans" +msgstr "Future plans" + +msgid "Get involved" +msgstr "Get involved" + +msgid "Grant number" +msgstr "Grant Number" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "Grant reference number if applicable [POST-AWARD DMPs ONLY]" + +msgid "Guidance" +msgstr "Guidance" + +#, fuzzy +msgid "Guidance choices saved." +msgstr "Guidance" + +msgid "Guidance group" +msgstr "Guidance group" + +msgid "Guidance group list" +msgstr "Guidance group list" + +msgid "Guidance group was successfully created." +msgstr "Guidance group was successfully created." + +msgid "Guidance group was successfully deleted." +msgstr "Guidance group was successfully deleted." + +msgid "Guidance group was successfully updated." +msgstr "Guidance group was successfully updated." + +msgid "Guidance list" +msgstr "Guidance list" + +msgid "Guidance was successfully created." +msgstr "Guidance was successfully created." + +msgid "Guidance was successfully deleted." +msgstr "Guidance was successfully deleted." + +msgid "Guidance was successfully updated." +msgstr "Guidance was successfully updated." + +msgid "Hello" +msgstr "Hello" + +msgid "Hello " +msgstr "Hello " + +msgid "Help" +msgstr "Help" + +msgid "History" +msgstr "History" + +msgid "Home" +msgstr "Home" + +msgid "How many plans?" +msgstr "How many plans?" + +msgid "How to use the API" +msgstr "How to use the API" + +msgid "ID" +msgstr "ID" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "If applying for funding, state the name exactly as in the grant proposal." + +#, fuzzy +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "If applying for funding, state the name exactly as in the grant proposal." + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "If you would like to change your password please complete the following fields." + +msgid "Included Elements" +msgstr "Included Elements" + +msgid "Information was successfully created." +msgstr "Information was successfully created." + +msgid "Information was successfully deleted." +msgstr "Information was successfully deleted." + +msgid "Information was successfully updated." +msgstr "Information was successfully updated." + +msgid "Institution" +msgstr "Institution" + +msgid "Invalid font face" +msgstr "Invalid font face" + +msgid "Invalid font size" +msgstr "Invalid font size" + +msgid "Invalid maximum pages" +msgstr "Invalid maximum pages" + +#, fuzzy +msgid "Invitation to %{email} issued successfully." +msgstr "Invitation issued successfully." + +msgid "Language" +msgstr "Language" + +msgid "Last logged in" +msgstr "Last logged in" + +msgid "Last name" +msgstr "Last name" + +msgid "Last updated" +msgstr "Last updated" + +msgid "Latest news" +msgstr "Latest news" + +msgid "Left" +msgstr "Left" + +msgid "List of users" +msgstr "List of users" + +msgid "Logo" +msgstr "Logo" + +msgid "Main organisation" +msgstr "Main organization" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "Margin" + +msgid "Margin cannot be negative" +msgstr "Margin cannot be negative" + +msgid "Margin value is invalid" +msgstr "Margin value is invalid" + +msgid "Me" +msgstr "Me" + +#, fuzzy +msgid "Message" +msgstr "Me" + +#, fuzzy +msgid "Modify guidance" +msgstr "guidance" + +#, fuzzy +msgid "Modify templates" +msgstr "template" + +msgid "Multi select box" +msgstr "Multi select box" + +#, fuzzy +msgid "My Plan" +msgstr "My plan" + +msgid "My organisation isn't listed." +msgstr "My organization isn't listed." + +msgid "My plans" +msgstr "My plans" + +#, fuzzy +msgid "My research organisation is not on the list" +msgstr "organization" + +msgid "Name" +msgstr "Name" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "Name (if different to above), telephone and email contact details" + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "Name of Principal Investigator(s) or main researcher(s) on the project." + +msgid "New guidance" +msgstr "New guidance" + +msgid "New password" +msgstr "New password" + +msgid "New section title" +msgstr "New section title" + +msgid "New template" +msgstr "New template" + +msgid "New to %{application_name}? Create an account today." +msgstr "New to %{application_name}? Create an account today." + +msgid "No" +msgstr "No" + +msgid "No additional comment area will be displayed." +msgstr "No additional comment area will be displayed." + +#, fuzzy +msgid "No funder associated with this plan" +msgstr "plan" + +#, fuzzy +msgid "No items available." +msgstr "No" + +msgid "No matches" +msgstr "No matches" + +msgid "None" +msgstr "None" + +msgid "Not answered yet" +msgstr "Not answered yet" + +msgid "Note" +msgstr "Note" + +msgid "Note removed by" +msgstr "Note removed by" + +msgid "Note removed by you" +msgstr "Note removed by you" + +msgid "Noted by:" +msgstr "Noted by:" + +msgid "Ok" +msgstr "Ok" + +msgid "On %{application_name}" +msgstr "On %{application_name}" + +msgid "On data management planning" +msgstr "On data management planning" + +msgid "Optional subset" +msgstr "Optional subset" + +msgid "Or, sign in with your institutional credentials" +msgstr "Or, sign in with your institutional credentials" + +msgid "Order" +msgstr "Order" + +msgid "Order of display" +msgstr "Order of display" + +msgid "Organisation" +msgstr "Organization" + +msgid "Organisation details" +msgstr "Organization details" + +msgid "Organisation name" +msgstr "Organization name" + +msgid "Organisation type" +msgstr "Organization type" + +msgid "Organisation was successfully updated." +msgstr "Organization was successfully updated." + +msgid "Organisational" +msgstr "Organizational" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "Organizational (visibile to others within your organization)" + +msgid "Organization" +msgstr "Organization" + +msgid "Original funder template has changed!" +msgstr "Original funder template has changed!" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "Own templates" + +msgid "Owner" +msgstr "Owner" + +msgid "PDF Formatting" +msgstr "PDF Formatting" + +msgid "Password" +msgstr "Password" + +msgid "Password and comfirmation must match" +msgstr "Password and confirmation must match" + +msgid "Password confirmation" +msgstr "Password confirmation" + +msgid "Permissions" +msgstr "Permissions" + +msgid "Phase details" +msgstr "Phase details" + +msgid "Plan Data Contact" +msgstr "Plan Data Contact" + +msgid "Plan Description" +msgstr "Plan Description" + +msgid "Plan ID" +msgstr "Plan ID" + +msgid "Plan Name" +msgstr "Plan Name" + +msgid "Plan data contact" +msgstr "Plan data contact" + +msgid "Plan details" +msgstr "Plan details" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "Plan name" + +msgid "Plan shared with %{email}." +msgstr "" + +msgid "Plan was successfully deleted." +msgstr "Plan was successfully deleted." + +msgid "Plan was successfully updated." +msgstr "Plan was successfully updated." + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +#, fuzzy +msgid "Please enter a First name." +msgstr "Please enter your first name." + +#, fuzzy +msgid "Please enter a Last name." +msgstr "Please enter your first name." + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "Please enter a title for your template." + +msgid "Please enter a valid web address." +msgstr "Please enter a valid web address." + +msgid "Please enter an email address" +msgstr "Please enter an email address" + +#, fuzzy +msgid "Please enter an email address." +msgstr "Please enter an email address" + +msgid "Please enter the name of your organisation." +msgstr "Please enter the name of your organization." + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "Please enter your first name." + +msgid "Please enter your organisation's name." +msgstr "Please enter your organization's name." + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "Please enter your surname or family name." + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "Please fill in the basic project details below and click 'Update' to save" + +#, fuzzy +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "

    Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in.

    " + +msgid "Please only enter up to 165 characters, you have used" +msgstr "Please only enter up to 165 characters, you have used" + +#, fuzzy +msgid "Please select an organisation, or select Other." +msgstr "organization" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "Preview" + +#, fuzzy +msgid "Primary research organisation" +msgstr "organization" + +msgid "Principal Investigator / Researcher" +msgstr "Principal Investigator / Researcher" + +msgid "Principal Investigator/Researcher" +msgstr "Principal Investigator/Researcher" + +msgid "Principal Investigator/Researcher ID" +msgstr "Principal Investigator/Researcher ID" + +msgid "Private" +msgstr "Private" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "Private (owners, co-owners, and administrators only) See our Terms of Use." + +msgid "Privileges" +msgstr "Permissions" + +msgid "Project title" +msgstr "" + +#, fuzzy +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "API token" + +msgid "Public" +msgstr "Public" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "Public (Your DMP will appear on the Public DMPs page of this site)" + +msgid "Public DMPs" +msgstr "Public DMPs" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." + +msgid "Publish" +msgstr "Publish" + +msgid "Publish changes" +msgstr "Publish changes" + +msgid "Published" +msgstr "Published" + +msgid "Question" +msgstr "Question" + +msgid "Question not answered" +msgstr "Question not answered." + +msgid "Question not answered." +msgstr "Question not answered." + +msgid "Question number" +msgstr "Question number" + +msgid "Question text" +msgstr "Question text" + +msgid "Question text is empty, please enter your question." +msgstr "Question text is empty, please enter your question." + +msgid "Questions" +msgstr "Questions" + +msgid "Radio buttons" +msgstr "Radio buttons" + +msgid "Read more on the " +msgstr "Read more on the " + +msgid "Read only" +msgstr "Read only" + +msgid "Releases" +msgstr "Releases" + +msgid "Remember me" +msgstr "Remember me" + +msgid "Remove" +msgstr "Remove" + +msgid "Remove user access" +msgstr "Remove user access" + +msgid "Reset" +msgstr "Reset" + +msgid "Right" +msgstr "Right" + +msgid "Save" +msgstr "Save" + +#, fuzzy +msgid "Save Unsuccessful." +msgstr "Save" + +msgid "Saving..." +msgstr "Saving..." + +msgid "Screencast on how to use %{application_name}" +msgstr "Screencast on how to use %{application_name}" + +msgid "Section" +msgstr "Section" + +msgid "Sections" +msgstr "Sections" + +#, fuzzy +msgid "Select a template" +msgstr "template" + +msgid "Select an action" +msgstr "Select an action" + +#, fuzzy +msgid "Select the funding organisation" +msgstr "organization" + +#, fuzzy +msgid "Select the primary research organisation responsible" +msgstr "organization" + +msgid "Select which group this guidance relates to." +msgstr "Select which group this guidance relates to." + +msgid "Select which theme(s) this guidance relates to." +msgstr "Select which theme(s) this guidance relates to." + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "Share" + +msgid "Share note" +msgstr "Share note" + +msgid "Share note with collaborators" +msgstr "Share note with collaborators" + +msgid "Sharing details successfully updated." +msgstr "Sharing details successfully updated." + +msgid "Should this guidance apply:" +msgstr "Should this guidance apply:" + +msgid "Sign in" +msgstr "Sign in" + +msgid "Sign out" +msgstr "Sign out" + +msgid "Signed in as " +msgstr "Signed in as " + +msgid "Size" +msgstr "Size" + +msgid "Someone has requested a link to change your " +msgstr "Someone has requested a link to change your " + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "Suggested answer" + +msgid "Suggested answer/ Example" +msgstr "Suggested answer/ Example" + +msgid "Super admin area" +msgstr "Super admin area" + +msgid "Template" +msgstr "Template" + +msgid "Template History" +msgstr "Template History" + +msgid "Template details" +msgstr "Template details" + +msgid "Templates" +msgstr "Templates" + +msgid "Terms of use" +msgstr "Terms of use" + +msgid "Test/Practice" +msgstr "Test/Practice" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "Test/Practice (your plan is not visible to other users) See our Terms of Use." + +msgid "Text" +msgstr "Text" + +msgid "Text area" +msgstr "Text area" + +msgid "Text field" +msgstr "Text field" + +msgid "Thank you for registering. Please confirm your email address" +msgstr "Thank you for registering. Please confirm your email address" + +msgid "That email address is already registered." +msgstr "That email address is already registered." + +msgid "That template is not currently published." +msgstr "That template is not currently published." + +#, fuzzy +msgid "The" +msgstr "The " + +msgid "The " +msgstr "The " + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "The email address of an administrator at your organization. Your users will use this address if they have questions." + +#, fuzzy +msgid "The following answer cannot be saved" +msgstr "The " + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." + +msgid "Themes" +msgstr "Themes" + +msgid "There are no public DMPs." +msgstr "There are no public DMPs." + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "There seems to be a problem with your logo. Please upload it again." + +msgid "These are the basic details for your organisation." +msgstr "These are the basic details for your organization." + +msgid "This allows you to order questions within a section." +msgstr "This allows you to order questions within a section." + +msgid "This allows you to order sections." +msgstr "This allows you to order sections." + +msgid "This allows you to order the phases of your template." +msgstr "This allows you to order the phases of your template." + +msgid "This document was generated by %{application_name}" +msgstr "This document was generated by %{application_name}" + +msgid "This must match what you entered in the previous field." +msgstr "This must match what you entered in the previous field." + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." + +#, fuzzy +msgid "This plan is based on the default template." +msgstr "template" + +msgid "This plan is based on:" +msgstr "This plan is based on:" + +msgid "This section is locked for editing by " +msgstr "This section is locked for editing by " + +msgid "Title" +msgstr "Title" + +msgid "Top" +msgstr "Top" + +msgid "Top banner text" +msgstr "Top banner text" + +msgid "Transfer customisation" +msgstr "" + +msgid "Un-published" +msgstr "Un-published" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "Unknown column name." + +msgid "Unknown formatting setting" +msgstr "Unknown formatting setting" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" + +msgid "Unlink account" +msgstr "Unlink account" + +msgid "Unlink institutional credentials alert" +msgstr "Unlink institutional credentials alert" + +msgid "Unlock my account" +msgstr "Unlock my account" + +msgid "Unpublish" +msgstr "Unpublish" + +msgid "Unpublished" +msgstr "Unpublished" + +msgid "Unpublished changes" +msgstr "Unpublished changes" + +msgid "Unsaved answers" +msgstr "Unsaved answers" + +msgid "Unsaved changes" +msgstr "Unsaved changes" + +msgid "Upload a new logo file" +msgstr "Upload a new logo file" + +msgid "Users" +msgstr "Users" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "Version" + +msgid "View" +msgstr "View" + +msgid "View all guidance" +msgstr "View all guidance" + +msgid "View all templates" +msgstr "View all templates" + +msgid "View phase" +msgstr "View phase" + +msgid "View plans" +msgstr "View plans" + +msgid "Visibility" +msgstr "Visibility" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "template" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "organization" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "template" + +msgid "Website" +msgstr "Website" + +msgid "Welcome to " +msgstr "Welcome to " + +msgid "Welcome to %{application_name}" +msgstr "Welcome to %{application_name}" + +msgid "Welcome." +msgstr "Welcome." + +#, fuzzy +msgid "What research project are you planning?" +msgstr "plan" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." + +#, fuzzy +msgid "Which DMP template would you like to use?" +msgstr "template" + +msgid "Would you like to save them now?" +msgstr "Would you like to save them now?" + +msgid "Yes" +msgstr "Yes" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "You are about to delete '%{guidance_summary}'. Are you sure?" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "You are about to delete '%{question_text}'. Are you sure?" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" + +#, fuzzy +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +#, fuzzy +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" + +msgid "You are not authorized to perform this action." +msgstr "" + +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "You are viewing a historical version of this template. You will not be able to make changes." + +#, fuzzy +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " + +msgid "You can edit any of the details below." +msgstr "You can edit any of the details below." + +#, fuzzy +msgid "You can not continue until you have filled in all of the required information." +msgstr "format" + +msgid "You can not edit a historical version of this template." +msgstr "" + +msgid "You can not publish a historical version of this template." +msgstr "" + +msgid "You cannot delete historical versions of this template." +msgstr "" + +msgid "You have altered answers but have not saved them:" +msgstr "You have altered answers but have not saved them:" + +msgid "You have been given " +msgstr "You have been given " + +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "You have been granted permission by your organization to use our API. Your API token and instructions for using the API endpoints can be found " + +msgid "You have un-published changes" +msgstr "" + +msgid "You have unsaved answers in the following sections:" +msgstr "" + +msgid "You must accept the terms and conditions to register." +msgstr "You must accept the terms and conditions to register." + +msgid "You must enter a valid email address." +msgstr "You must enter a valid email address." + +msgid "You need to sign in or sign up before continuing." +msgstr "You need to sign in or sign up before continuing." + +msgid "You now have " +msgstr "" + +msgid "Your" +msgstr "Your" + +msgid "Your ORCID" +msgstr "Your ORCID" + +msgid "Your access to " +msgstr "Your access to " + +msgid "Your account has been successfully linked to %{scheme}." +msgstr "Your account has been successfully linked to %{scheme}." + +msgid "Your account won't be created until you access the link above and set your password." +msgstr "Your account won't be created until you access the link above and set your password." + +msgid "Your browser does not support the video tag." +msgstr "Your browser does not support the video tag." + +msgid "Your password must contain at least 8 characters." +msgstr "Your password must contain at least 8 characters." + +msgid "Your permissions relating to " +msgstr "Your permissions relating to " + +msgid "Your template has been published and is now available to users." +msgstr "Your template has been published and is now available to users." + +msgid "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" +msgstr "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" + +msgid "a day" +msgstr "a day" + +msgid "about %d hours" +msgstr "about %d hours" + +msgid "about a minute" +msgstr "about a minute" + +msgid "about a month" +msgstr "about a month" + +msgid "about a year" +msgstr "about a year" + +msgid "about an hour" +msgstr "about an hour" + +msgid "account has been locked due to an excessive number of unsuccessful sign in attempts." +msgstr "account has been locked due to an excessive number of unsuccessful sign in attempts." + +msgid "activerecord.errors.messages.record_invalid" +msgstr "unable to save your changes" + +msgid "activerecord.errors.models.user.attributes.current_password.invalid" +msgstr "invalid email and/or password" + +msgid "activerecord.errors.models.user.attributes.email.blank" +msgstr "can't be blank" + +msgid "activerecord.errors.models.user.attributes.password.blank" +msgstr "can't be blank" + +msgid "activerecord.errors.models.user.attributes.password_confirmation.confirmation" +msgstr "passwords must match" + +msgid "add guidance text" +msgstr "add guidance text" + +# Timeago - found in lib/assets/javascripts/jquery.timeago.js +# --------------------- +# suffix ago +msgid "ago" +msgstr "ago" + +msgid "approx. %{space_used}%% of available space used (max %{num_pages} pages)" +msgstr "approx. %{space_used}%% of available space used (max %{num_pages} pages)" + +#, fuzzy +msgid "by " +msgstr " by " + +msgid "can't be blank" +msgstr "" + +msgid "can't be larger than 500KB" +msgstr "" + +msgid "can't be less than zero" +msgstr "" + +msgid "e.g. School/ Department" +msgstr "e.g. School/ Department" + +#, fuzzy +msgid "example answer" +msgstr "Example of answer" + +msgid "from now" +msgstr "from now" + +#, fuzzy +msgid "generic template" +msgstr "template" + +msgid "guidance" +msgstr "guidance" + +msgid "guidance group" +msgstr "guidance group" + +msgid "guidance on" +msgstr "guidance on" + +msgid "height must be less than 100px" +msgstr "" + +msgid "helpers.is_test" +msgstr "" + +msgid "helpers.links.cancel" +msgstr "" + +msgid "helpers.project.is_test_help_text" +msgstr "" + +msgid "into your browser" +msgstr "into your browser" + +msgid "less than a minute" +msgstr "less than a minute" + +msgid "must be logged in" +msgstr "must be logged in" + +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" + +msgid "must be unique" +msgstr "" + +msgid "must have access to guidances api" +msgstr "must have access to guidances api" + +#, fuzzy +msgid "must have access to plans api" +msgstr "must have access to guidances api" + +#, fuzzy +msgid "no research organisation is associated with this plan" +msgstr "organization" + +msgid "note" +msgstr "note" + +msgid "or copy" +msgstr "or copy" + +msgid "organisation" +msgstr "organization" + +msgid "phase" +msgstr "phase" + +msgid "plan" +msgstr "plan" + +msgid "profile" +msgstr "" + +msgid "question" +msgstr "question" + +msgid "questions answered" +msgstr "questions answered" + +msgid "role" +msgstr "role" + +msgid "section" +msgstr "section" + +msgid "select a guidance group" +msgstr "select a guidance group" + +msgid "select at least one theme" +msgstr "select at least one theme" + +#, fuzzy +msgid "since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again." +msgstr " on " + +msgid "template" +msgstr "template" + +msgid "user" +msgstr "user" + +#, fuzzy +msgid "user must be in your organisation" +msgstr "organization" diff --git a/config/locale/es/app.po b/config/locale/es/app.po new file mode 100644 index 0000000..c921f5c --- /dev/null +++ b/config/locale/es/app.po @@ -0,0 +1,1818 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2017-05-02 14:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr " (sólo usuarios del Reino Unido)" + +msgid " - " +msgstr "" + +#, fuzzy +msgid " I accept the terms and conditions *" +msgstr " Acepto los términos y condiciones *" + +#, fuzzy +msgid " Plan" +msgstr "plans" + +msgid " access to" +msgstr "" + +msgid " access. " +msgstr "" + +msgid " and " +msgstr "" + +#, fuzzy +msgid " by" +msgstr " por " + +msgid " by " +msgstr " por " + +#, fuzzy +msgid " has been removed by " +msgstr " por " + +#, fuzzy +msgid " have been changed by" +msgstr " por " + +msgid " into your browser)" +msgstr "" + +msgid " on " +msgstr "" + +msgid " or " +msgstr "" + +msgid " password. You can do this through the link below." +msgstr "" + +#, fuzzy +msgid " provided by " +msgstr " por " + +#, fuzzy +msgid " team" +msgstr "am" + +#, fuzzy +msgid " that has been customised by " +msgstr " por " + +msgid " to accept the invitation, (or copy " +msgstr "" + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr "" + +#, fuzzy +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "ID" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "" + +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "" + +msgid "%d days" +msgstr "" + +msgid "%d minutes" +msgstr "" + +msgid "%d months" +msgstr "" + +msgid "%d years" +msgstr "" + +msgid "%{application_name}" +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "DMPonline" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "" + +msgid "%{value} is not a valid format" +msgstr "" + +msgid "(Using custom PDF formatting values)" +msgstr "(Usando valores personalizados para el formato del PDF)" + +msgid "(Using template PDF formatting values)" +msgstr "(Usando valores de la plantilla para el formato del template PDF)" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "

    Preguntas a considerar:

    • - ¿Cual es la naturaleza de su proyecto de investigación?
    • - ¿Qué temas de investigación está tratando?
    • - ¿Para qué propósito se están recogiendo o creando los datos?

    Orientación:

    Resuma brevemente el tipo de estudio (o estudios) para ayudar a otros a comprender los propósitos para los cuales se están recogiendo o crendo los datos.

    " + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "
    Teclee una descripción básica. Puede ser un resumen sobre que cubre esta sección o instrucciones sobre como responder las preguntas. Este texto se mostrará en un banner cada vez que se edite esta sección.
    " + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "
    Introduzca una descripción que ayude a distinguir las plantillas. Ej: Si van dirigidas a audiencias distintas.
    " + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "" + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "" + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "

    DMPonline ha sido desarrollado por el Digital Curation Centre como una herramienta para elaborar planes de gestión de datos.

    " + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "" + +#, fuzzy +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "" + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "

    Bienvenido.
    Ya está listo para crear su primer PGD.
    Haga clic en el botón 'Crear un plan' para comenzar.

    " + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "

    Primero cree un grupo de guías. Este podrá abarcar toda la institución o un subconjunto de la misma (ej: una escuela, colegio o departamento en particular). Cuando cree una guía, necesitará asignarla a un grupo de guías.

    " + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "

    Desde aquí puede descargar su plan en varios formatos. Esto puede ser útil si necesita enviar su plan para solicitar una subvención.
    Seleccione qué formato quiere usar y haga clic en 'Exportar'.

    " + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "" + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "" + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "

    Aquí indicará el título mostrado a los usuarios. Si piensa tener varias fases en su PGD, esto debería quedar claro en el título y la descripción.

    " + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "

    Si desea añadir una plantilla institucional para un Plan de Gestión de Datos, use el botón 'crear plantilla'. Podrá crear más de una plantilla si lo cree conveniente. Ej: para investigadores y otro para estudiantes de postgrado.

    Su plantilla se presentará a los usuarios de su institución cuando no sean aplicables plantillas de agencias de financiación. Si quiere aññadir preguntas a las plantillas de las agencias de financiación, use las siguientes opciones de 'personalizar plantilla'

    " + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "

    Seleccione los temas relevantes para esta pregunta.

    Le permite crear guías genéricas a nivel de institución o de otras fuentes. Ej. para el DCC o cualquier escuela o departamento a la que se dirija la guía.

    Puede seleccionar varios temas usando el botón CTRL.

    " + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "" + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "

    La siguiente tabla lista los planes que usted ha creado, así como los que otros investigadores hayan compartido con usted.
    Se pueden editar, compartir, exportar o borrar en cualquier momento.

    " + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "

    Para crear una plantilla nueva, en primer lugar introduzca un título y una descripción. Tras grabar se le dará la opción de añadir una o más fases.

    " + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "" + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "

    Va a desvincular DMPonline de las credenciales de su institución, ¿Quiere continuar?

    " + +#, fuzzy +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "

    Aquí puede dar a otras personas acceso a su plan. Hay tres niveles de permiso.

    • Los usuarios con acceso de \"sólo lectura\" sólo pueden leer el plan.
    • Los Editores pueden contribuir al plan.
    • Los Co-propietarios pueden también contribuir, editar los detalles y controlar el acceso al plan.

    Añada cada colaborador individualmente introduciendo su dirección de correo electrónico, seleccionando un nivel de permiso y haciendo clic en \"Añadir colaborador\".

    Aquellos a quienes invite recibirán un aviso por correo electrónico indicando que tienen acceso al plan e invitándoles a registrarse en DMPonline si no tienen ya una cuenta. También se envia un aviso si se cambia el nivel de permiso de un usuario.

    " + +#, fuzzy +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "templates" + +#, fuzzy +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "DMPonline" + +#, fuzzy +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "DMPonline" + +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "" + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "El ID tal como lo determinó la institución u organismo financiador." + +msgid "A required setting has not been provided" +msgstr "No se ha indicado un valor obligatorio" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "" + +msgid "Abbreviation" +msgstr "Abreviatura" + +msgid "About" +msgstr "Acerca de" + +msgid "About %{application_name}" +msgstr "" + +msgid "Access removed" +msgstr "" + +msgid "Actions" +msgstr "Acciones" + +msgid "Add Annotations" +msgstr "" + +#, fuzzy +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "Grupo de orientación" + +msgid "Add collaborator" +msgstr "Añadir colaborador" + +msgid "Add guidance" +msgstr "Añadir orientación" + +msgid "Add guidance group" +msgstr "Añadir grupo de orientación" + +msgid "Add new phase +" +msgstr "Añadir fase nueva +" + +msgid "Add note" +msgstr "Añadir nota" + +msgid "Add option" +msgstr "Añadir opción" + +msgid "Add question" +msgstr "Añadir pregunta" + +msgid "Add section" +msgstr "Añadir sección" + +msgid "Additional comment area will be displayed." +msgstr "Se mostrará un área adicional para comentarios." + +msgid "Admin Details" +msgstr "" + +msgid "Admin area" +msgstr "Área de administración" + +msgid "All the best," +msgstr "" + +#, fuzzy +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "Organización" + +#, fuzzy +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "Organización" + +#, fuzzy +msgid "Allows the user to create and edit guidance" +msgstr "user" + +#, fuzzy +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "templates" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +#, fuzzy +msgid "Answer" +msgstr "Respuestas" + +msgid "Answer format" +msgstr "Formato de la respuesta" + +msgid "Answer questions" +msgstr "Responder" + +#, fuzzy +msgid "Answered" +msgstr "Contestado " + +#, fuzzy +msgid "Answered at" +msgstr "Contestado " + +#, fuzzy +msgid "Answered by" +msgstr "Contestado " + +msgid "Answers" +msgstr "Respuestas" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "Cualquier texto que introduzca aquí se mostrará en la caja de respuesta. Si quiere una respuesta en un formato concreto (ej: tablas), puede crear ese estilo aquí." + +#, fuzzy +msgid "Are you sure you want to remove this note?" +msgstr "¿Seguro que quiere eliminar esta nota?" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "¿Está seguro de que quiere borrar este plan?" + +msgid "Are you sure?" +msgstr "¿Está seguro?" + +msgid "Back" +msgstr "Volver" + +msgid "Back to edit view" +msgstr "Volver a editar la vista" + +msgid "Background" +msgstr "Volver" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "" + +#, fuzzy +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "Preguntas" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "Debajo tiene la lista de usuarios registrados en su entidad. Puede ordenar los datos por campo." + +msgid "Bottom" +msgstr "Inferior" + +msgid "By " +msgstr "" + +msgid "Cancel" +msgstr "Cancelar" + +#, fuzzy +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "plans" + +msgid "Change language" +msgstr "" + +#, fuzzy +msgid "Change my password" +msgstr "Cambiar su clave" + +#, fuzzy +msgid "Change organisation details" +msgstr "Organización" + +msgid "Check box" +msgstr "Check box" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "" + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "" + +msgid "Click here to confirm your account" +msgstr "" + +msgid "Click the link below to unlock your account" +msgstr "" + +msgid "Co-owner" +msgstr "Co-propietario" + +msgid "Collaborators" +msgstr "Colaboradores" + +msgid "Comment" +msgstr "Comentario" + +#, fuzzy +msgid "Comment removed." +msgstr "Comentario" + +msgid "Comment was successfully created." +msgstr "" + +#, fuzzy +msgid "Comment was successfully saved." +msgstr "Plan creado con éxito" + +msgid "Contact Email" +msgstr "" + +#, fuzzy +msgid "Contact Us" +msgstr "Contacto" + +msgid "Contact us" +msgstr "Contacto" + +msgid "Create a new plan" +msgstr "Crear un nuevo plan" + +msgid "Create a template" +msgstr "Crear una plantilla" + +msgid "Create account" +msgstr "Registrarse" + +msgid "Create plan" +msgstr "Crear un plan" + +msgid "Created" +msgstr "Creación" + +msgid "Created at" +msgstr "Creado el" + +msgid "Current password" +msgstr "Clave actual" + +msgid "Customise" +msgstr "Personalizar" + +msgid "Default" +msgstr "Por defecto" + +msgid "Default answer" +msgstr "Respuesta por defecto" + +msgid "Default value" +msgstr "Valor por defecto" + +msgid "Delete" +msgstr "Borrar" + +#, fuzzy +msgid "Delete Example Answer" +msgstr "Respuesta de ejemplo" + +msgid "Delete question" +msgstr "Borrar la pregunta" + +msgid "Description" +msgstr "" + +msgid "Details" +msgstr "Detalles" + +msgid "Details successfully updated." +msgstr "" + +msgid "Didn't receive confirmation instructions?" +msgstr "¿No recibió instrucciones de confirmación?" + +msgid "Didn't receive unlock instructions?" +msgstr "¿No recibió instrucciones para el desbloqueo?" + +msgid "Discard" +msgstr "Descartar" + +msgid "Display additional comment area." +msgstr "Mostrar un área de comentarios adicional." + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "Dropdown" + +msgid "E.g ORCID http://orcid.org/." +msgstr "P.e. ORCID http://orcid.org/." + +msgid "Edit" +msgstr "Editar" + +#, fuzzy +msgid "Edit Annotations" +msgstr "Editar" + +msgid "Edit User Privileges" +msgstr "" + +msgid "Edit customisation" +msgstr "Editar la personalización" + +msgid "Edit phase" +msgstr "Editar fase" + +msgid "Edit phase details" +msgstr "Editar los detalles de las fase" + +msgid "Edit plan details" +msgstr "Editar los detalles del plan" + +msgid "Edit profile" +msgstr "Editar perfil" + +msgid "Edit question" +msgstr "Editar la pregunta" + +msgid "Edit template details" +msgstr "Editar plantilla" + +#, fuzzy +msgid "Editor" +msgstr "Editar" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "Los editores pueden contribuir a los planes. Los co-propietarios tienen derechos adicionales para editar los detalles del plan y controlar el acceso al mismo." + +msgid "Email" +msgstr "Correo electrónico" + +msgid "Email address" +msgstr "Dirección de correo electrónico" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "Teclee una descripción básica. Se les presentará a los usuarios bajo el resumen de secciones y preguntas solicitadas." + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "Introduzca una descripción que le ayude a diferenciar las plantillas. Ej: Si tiene varias para diferentes audiencias" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "Por favor, introduzca un título para la fase" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "Introduzca las opciones que quiere mostrar. Si quiere que una opción esté seleccionada por defecto, marque la casilla correspondiente." + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "Introduzca la guía concreta para esta pregunta. Si también tiene guías temáticas, se eligirán en función de su slección, por lo que es preferible no duplicar mucho texto." + +msgid "Enter your guidance here. You can include links where needed." +msgstr "Introduzca sus orientaciones aquí. Puede incluir enlaces si lo cree necesario." + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "" + +msgid "Error!" +msgstr "¡Error!" + +#, fuzzy +msgid "Example Answer" +msgstr "Respuesta de ejemplo" + +#, fuzzy +msgid "Example of answer" +msgstr "Respuesta de ejemplo" + +msgid "Export" +msgstr "Exportar" + +#, fuzzy +msgid "Export settings updated successfully." +msgstr "Exportar" + +#, fuzzy +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "Exportar" + +msgid "Face" +msgstr "Estilo" + +msgid "File Name" +msgstr "Título del plan" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "Filtro de planes" + +msgid "First name" +msgstr "Nombre" + +msgid "Font" +msgstr "" + +msgid "Forgot your password?" +msgstr "¿Olvidó su clave?" + +msgid "Format" +msgstr "" + +msgid "Funder" +msgstr "Financiador" + +msgid "Funders templates" +msgstr "Plantillas de financiador" + +#, fuzzy +msgid "Funding organisation" +msgstr "Organización" + +msgid "Future plans" +msgstr "Hoja de ruta" + +msgid "Get involved" +msgstr "" + +msgid "Grant number" +msgstr "Título de subvención" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "Número de referencia de la subvención si es aplicable [SÓLO PGDs YA ADJUDICADOS]" + +msgid "Guidance" +msgstr "Guía" + +#, fuzzy +msgid "Guidance choices saved." +msgstr "Guía" + +msgid "Guidance group" +msgstr "Grupo de orientación" + +msgid "Guidance group list" +msgstr "Listado de grupos de orientación" + +msgid "Guidance group was successfully created." +msgstr "El grupo de orientación se creó correctamente." + +msgid "Guidance group was successfully deleted." +msgstr "El grupo de orientación se borró correctamente." + +msgid "Guidance group was successfully updated." +msgstr "El grupo de orientación se actualizó correctamente." + +msgid "Guidance list" +msgstr "Listado de orientaciones" + +msgid "Guidance was successfully created." +msgstr "La orientación se creó correctamente." + +#, fuzzy +msgid "Guidance was successfully deleted." +msgstr "La orientación se creó correctamente." + +msgid "Guidance was successfully updated." +msgstr "La orientación se actualizó correctamente." + +msgid "Hello" +msgstr "" + +msgid "Hello " +msgstr "" + +msgid "Help" +msgstr "Ayuda" + +msgid "History" +msgstr "" + +msgid "Home" +msgstr "Inicio" + +msgid "How many plans?" +msgstr "¿Cuántos planes?" + +msgid "How to use the API" +msgstr "" + +msgid "ID" +msgstr "ID" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "Si se solicita financiación, indique el nombre exactamente como en la propuesta de subvención." + +#, fuzzy +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "Si se solicita financiación, indique el nombre exactamente como en la propuesta de subvención." + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "Si la guía está dirigida a un subconjunto de los usuarios (ej: los pertenecientes a un colegio o instituto), seleccione esta opción. Los usuarios serán capaces de seleccionar esta guía cuando respondan sus preguntas durante la creación del plan." + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "" + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "" + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "Si quiere cambiar su clave, por favor, rellene los siguientes campos." + +msgid "Included Elements" +msgstr "Elementos incluídos" + +msgid "Information was successfully created." +msgstr "La información se creó correctamente." + +msgid "Information was successfully deleted." +msgstr "Information se destruyó correctamente" + +msgid "Information was successfully updated." +msgstr "La información se actualizó correctamente." + +msgid "Institution" +msgstr "Institución" + +msgid "Invalid font face" +msgstr "Estilo de fuente inválido" + +msgid "Invalid font size" +msgstr "Tamaño de fuente inválido" + +msgid "Invalid maximum pages" +msgstr "Número de páginas inválido" + +msgid "Invitation to %{email} issued successfully." +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Last logged in" +msgstr "Último acceso" + +msgid "Last name" +msgstr "Apellidos" + +msgid "Last updated" +msgstr "Última actualización" + +msgid "Latest news" +msgstr "" + +msgid "Left" +msgstr "Izquierdo" + +msgid "List of users" +msgstr "Listado de usuarios" + +msgid "Logo" +msgstr "" + +msgid "Main organisation" +msgstr "Entidad principal" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "Margen" + +msgid "Margin cannot be negative" +msgstr "El margen no puede ser negativo" + +msgid "Margin value is invalid" +msgstr "El valor del margen no es válido" + +msgid "Me" +msgstr "Yo" + +#, fuzzy +msgid "Message" +msgstr "Yo" + +#, fuzzy +msgid "Modify guidance" +msgstr "Añadir orientación" + +#, fuzzy +msgid "Modify templates" +msgstr "templates" + +msgid "Multi select box" +msgstr "Multi select box" + +#, fuzzy +msgid "My Plan" +msgstr "Mi proyecto" + +msgid "My organisation isn't listed." +msgstr "No se muestra mi organización." + +msgid "My plans" +msgstr "Mis planes" + +#, fuzzy +msgid "My research organisation is not on the list" +msgstr "Organización" + +msgid "Name" +msgstr "Nombre" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "Nombre (si es diferente del de más arriba), teléfono y dirección de correo electrónico" + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "Nombre del/de los Investigador/es Principal/es o investigador/es principal/es del proyecto." + +msgid "New guidance" +msgstr "Nueva orientación" + +msgid "New password" +msgstr "Nueva clave" + +msgid "New section title" +msgstr "Título de la nueva sección" + +msgid "New template" +msgstr "Nueva plantilla" + +msgid "New to %{application_name}? Create an account today." +msgstr "¿Nuevo en DMPonline? Regístrese ya." + +msgid "No" +msgstr "" + +msgid "No additional comment area will be displayed." +msgstr "No se mostrará un área adicional para comentarios." + +#, fuzzy +msgid "No funder associated with this plan" +msgstr "plans" + +msgid "No items available." +msgstr "" + +msgid "No matches" +msgstr "Ningún plan coincide con '%{filter}'" + +msgid "None" +msgstr "Ninguno/a" + +msgid "Not answered yet" +msgstr "Aún no respondido/a" + +msgid "Note" +msgstr "Nota" + +msgid "Note removed by" +msgstr "Nota borrada por" + +msgid "Note removed by you" +msgstr "Nota borrada por usted" + +msgid "Noted by:" +msgstr "Anotado por:" + +msgid "Ok" +msgstr "" + +msgid "On %{application_name}" +msgstr "" + +msgid "On data management planning" +msgstr "" + +msgid "Optional subset" +msgstr "Subconjunto opcional" + +msgid "Or, sign in with your institutional credentials" +msgstr "O conectar con sus credenciales institucionales" + +msgid "Order" +msgstr "Orden" + +msgid "Order of display" +msgstr "Orden de presentación" + +msgid "Organisation" +msgstr "Organización" + +msgid "Organisation details" +msgstr "Detalles de la entidad" + +msgid "Organisation name" +msgstr "Nombre de la entidad" + +msgid "Organisation type" +msgstr "Tipo de entidad" + +msgid "Organisation was successfully updated." +msgstr "Se ha actualizado correctamente la actualización." + +msgid "Organisational" +msgstr "Organizativo" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "Con otros miembros de su organización" + +msgid "Organization" +msgstr "Organización" + +#, fuzzy +msgid "Original funder template has changed!" +msgstr "templates" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "Sus plantillas" + +msgid "Owner" +msgstr "Propietario" + +msgid "PDF Formatting" +msgstr "Dando formato al PDF" + +msgid "Password" +msgstr "Clave" + +#, fuzzy +msgid "Password and comfirmation must match" +msgstr "Clave" + +msgid "Password confirmation" +msgstr "Confirmación de clave" + +msgid "Permissions" +msgstr "Permisos" + +msgid "Phase details" +msgstr "Detalles de la fase" + +msgid "Plan Data Contact" +msgstr "Datos de contacto del proyecto" + +msgid "Plan Description" +msgstr "Descripción" + +msgid "Plan ID" +msgstr "Identificador del Proyecto" + +msgid "Plan Name" +msgstr "Nombre del Proyecto" + +msgid "Plan data contact" +msgstr "Datos de contacto del plan" + +msgid "Plan details" +msgstr "Detalles" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "Nombre de proyecto" + +msgid "Plan shared with %{email}." +msgstr "" + +#, fuzzy +msgid "Plan was successfully deleted." +msgstr "Plan creado con éxito" + +msgid "Plan was successfully updated." +msgstr "" + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +#, fuzzy +msgid "Please enter a First name." +msgstr "Por favor, introduzca su nombre." + +#, fuzzy +msgid "Please enter a Last name." +msgstr "Por favor, introduzca su nombre." + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "Por favor, introduzca un título para la plantilla." + +msgid "Please enter a valid web address." +msgstr "Por favor, introduzca una dirección web válida." + +msgid "Please enter an email address" +msgstr "" + +#, fuzzy +msgid "Please enter an email address." +msgstr "Por favor, introduzca una dirección web válida." + +msgid "Please enter the name of your organisation." +msgstr "Por favor, introduzca el nombre de su entidad." + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "Por favor, introduzca su nombre." + +msgid "Please enter your organisation's name." +msgstr "Por favor, introduzca el nombre de su entidad." + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "Por favor, introduzca sus apellidos." + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "Por favor, rellene los detalles básicos del proyecto y haga clic en 'Actualizar' para guardarlos" + +#, fuzzy +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "

    Por favor, tenga en cuenta que su dirección de correo electrónico se usa como su nombre de usuario. Si cambia esto, recuerde usar su nueva dirección de correo electrónico al conectar.

    " + +msgid "Please only enter up to 165 characters, you have used" +msgstr "" + +#, fuzzy +msgid "Please select an organisation, or select Other." +msgstr "Organización" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "Previsualización" + +#, fuzzy +msgid "Primary research organisation" +msgstr "Organización" + +msgid "Principal Investigator / Researcher" +msgstr "Principal Investigador / Científico" + +msgid "Principal Investigator/Researcher" +msgstr "Investigador principal" + +msgid "Principal Investigator/Researcher ID" +msgstr "ID del Investigador Principal" + +msgid "Private" +msgstr "Privado" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "Privado (propietarios, copropietarios y administradores solamente) Consulte nuestras Condiciones de uso." + +msgid "Privileges" +msgstr "" + +msgid "Project title" +msgstr "" + +#, fuzzy +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "user" + +msgid "Public" +msgstr "Público" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "Publicamente en la web. Su DMP aparecerá en la página Public DMPs de este sitio." + +msgid "Public DMPs" +msgstr "DMP Públicos" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "DMP Públicos" + +msgid "Publish" +msgstr "" + +msgid "Publish changes" +msgstr "" + +msgid "Published" +msgstr "Publicado" + +msgid "Question" +msgstr "Pregunta" + +msgid "Question not answered" +msgstr "Pregunta no respondida." + +msgid "Question not answered." +msgstr "Pregunta no respondida." + +msgid "Question number" +msgstr "Número de la pregunta" + +msgid "Question text" +msgstr "Texto de la pregunta" + +msgid "Question text is empty, please enter your question." +msgstr "" + +msgid "Questions" +msgstr "Preguntas" + +msgid "Radio buttons" +msgstr "Radio buttons" + +msgid "Read more on the " +msgstr "" + +msgid "Read only" +msgstr "Sólo lectura" + +msgid "Releases" +msgstr "" + +msgid "Remember me" +msgstr "Recordarme" + +msgid "Remove" +msgstr "Borrar" + +msgid "Remove user access" +msgstr "Eliminar acceso de usuario" + +msgid "Reset" +msgstr "Reiniciar" + +msgid "Right" +msgstr "Derecho" + +msgid "Save" +msgstr "Guardar" + +#, fuzzy +msgid "Save Unsuccessful." +msgstr "Guardar" + +msgid "Saving..." +msgstr "Guardando..." + +msgid "Screencast on how to use %{application_name}" +msgstr "Video sobre cómo usar DMPonline" + +msgid "Section" +msgstr "Sección" + +msgid "Sections" +msgstr "Secciones" + +#, fuzzy +msgid "Select a template" +msgstr "templates" + +msgid "Select an action" +msgstr "Seleccionar una acción" + +#, fuzzy +msgid "Select the funding organisation" +msgstr "Organización" + +#, fuzzy +msgid "Select the primary research organisation responsible" +msgstr "Organización" + +msgid "Select which group this guidance relates to." +msgstr "Seleccione a que grupo pertenece esta guía." + +msgid "Select which theme(s) this guidance relates to." +msgstr "Seleccione a el/los tema(s) relacionados con esta orientación." + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "Compartir" + +msgid "Share note" +msgstr "Compartir nota" + +msgid "Share note with collaborators" +msgstr "Compartir nota con colaboradores" + +msgid "Sharing details successfully updated." +msgstr "" + +msgid "Should this guidance apply:" +msgstr "Esta guía se refiere a:" + +msgid "Sign in" +msgstr "Conectar" + +msgid "Sign out" +msgstr "Desconectar" + +msgid "Signed in as " +msgstr "Registrado como " + +msgid "Size" +msgstr "Tamaño" + +msgid "Someone has requested a link to change your " +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "Respuesta sugerida" + +msgid "Suggested answer/ Example" +msgstr "Respuesta sugerida / ejemplo" + +msgid "Super admin area" +msgstr "Área de super administrador" + +msgid "Template" +msgstr "Modelo" + +msgid "Template History" +msgstr "" + +msgid "Template details" +msgstr "Detalles de la plantilla" + +msgid "Templates" +msgstr "Plantillas" + +msgid "Terms of use" +msgstr "" + +msgid "Test/Practice" +msgstr "Prueba/Práctica" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "Prueba / Práctica (su plan no es visible para otros usuarios) Vea nuestras Condiciones de uso." + +msgid "Text" +msgstr "Texto" + +msgid "Text area" +msgstr "Text area" + +msgid "Text field" +msgstr "Text field" + +msgid "Thank you for registering. Please confirm your email address" +msgstr "" + +msgid "That email address is already registered." +msgstr "" + +#, fuzzy +msgid "That template is not currently published." +msgstr "templates" + +msgid "The" +msgstr "" + +msgid "The " +msgstr "" + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "" + +msgid "The following answer cannot be saved" +msgstr "" + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "Los items que seleccione se mostarán en la siguiente tabla. Puede ordenar los datos según sus encabezados o filtrar tecleando textos en la caja de búsqueda." + +msgid "Themes" +msgstr "Temas" + +msgid "There are no public DMPs." +msgstr "" + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "" + +msgid "These are the basic details for your organisation." +msgstr "Estos son los detalles básicos de su entidad." + +msgid "This allows you to order questions within a section." +msgstr "Le permite ordenar las preguntas de una sección." + +msgid "This allows you to order sections." +msgstr "Le permite ordenar las secciones." + +msgid "This allows you to order the phases of your template." +msgstr "Esto le permite ordenar las fases de su plantilla." + +msgid "This document was generated by %{application_name}" +msgstr "DMPonline" + +msgid "This must match what you entered in the previous field." +msgstr "Ha de coincidir con lo que introdujo en el campo anterior." + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "Esta página le proporciona una visión general de su plan. Le dice en qué está basado su plan y le da una visión general de las preguntas que se le harán." + +#, fuzzy +msgid "This plan is based on the default template." +msgstr "templates" + +msgid "This plan is based on:" +msgstr "Este plan está basado en:" + +msgid "This section is locked for editing by " +msgstr "Esta sección está bloqueda para su edición por " + +msgid "Title" +msgstr "Título" + +msgid "Top" +msgstr "Superior" + +msgid "Top banner text" +msgstr "Texto del banner superior" + +msgid "Transfer customisation" +msgstr "" + +#, fuzzy +msgid "Un-published" +msgstr "Publicado" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "Nombre de columna desconocido." + +msgid "Unknown formatting setting" +msgstr "Valores de formato desconocidos" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "Margen desconocido. Sólo puede ser 'superior', 'inferior', 'izquierdo' or 'derecho'" + +msgid "Unlink account" +msgstr "Desvincular cuenta" + +msgid "Unlink institutional credentials alert" +msgstr "Desvincule las alertas relacionadas con las credenciales de su institución" + +msgid "Unlock my account" +msgstr "" + +msgid "Unpublish" +msgstr "" + +#, fuzzy +msgid "Unpublished" +msgstr "Publicado" + +msgid "Unpublished changes" +msgstr "" + +msgid "Unsaved answers" +msgstr "Preguntas sin contestar" + +msgid "Unsaved changes" +msgstr "Deshaciendo cambios" + +msgid "Upload a new logo file" +msgstr "" + +msgid "Users" +msgstr "Usuarios" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "Versión" + +msgid "View" +msgstr "Ver" + +msgid "View all guidance" +msgstr "Ver todas las orientaciones" + +msgid "View all templates" +msgstr "Ver todas las plantillas" + +msgid "View phase" +msgstr "Ver fase" + +msgid "View plans" +msgstr "Ver planes" + +msgid "Visibility" +msgstr "Visibilidad" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "templates" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "Organización" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "templates" + +msgid "Website" +msgstr "Sitio web" + +#, fuzzy +msgid "Welcome to " +msgstr "Bienvenido/a." + +msgid "Welcome to %{application_name}" +msgstr "" + +msgid "Welcome." +msgstr "Bienvenido/a." + +#, fuzzy +msgid "What research project are you planning?" +msgstr "plans" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "Cuando crea una fase nueva para su plantilla, se creará automáticamente una versión. Una vez complete el siguiente formulario se le darán las opciones para crear secciones y preguntas." + +#, fuzzy +msgid "Which DMP template would you like to use?" +msgstr "templates" + +msgid "Would you like to save them now?" +msgstr "¿Quere grabar los cambios ahora?" + +msgid "Yes" +msgstr "" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "Está a punto de borrar el grupo '%{guidance_group_name}'. Esto afectará a la orientación. ¿Está seguro?" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "Está a punto de borrar '%{guidance_summary}'. ¿Está seguro?" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "Va a eliminar '%{phase_title}'. Esto afectará a versiones, secciones y preguntas enlazadas con esta fase. ¿Está seguro?" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "Va a eliminar '%{question_text}'. ¿Está seguro?" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "Va a borrar '%{section_title}'. Esta acción afectará las preguntas enlazadas con esta sección. ¿Está seguro?" + +#, fuzzy +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "Va a eliminar una respuesta sugerida / ejemplo de '%{question_text}'. ¿Está seguro?" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "Va a eliminar una respuesta sugerida / ejemplo de '%{question_text}'. ¿Está seguro?" + +#, fuzzy +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "Va a eliminar una respuesta sugerida / ejemplo de '%{question_text}'. ¿Está seguro?" + +msgid "You are not authorized to perform this action." +msgstr "" + +#, fuzzy +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "templates" + +#, fuzzy +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Puede añadir un ejemplo o respuesta sugerida para ayudar a responder a sus usuarios. Se presentará bajo la caja de respuestas y pueden ser copiada y pegada." + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Puede añadir un ejemplo o respuesta sugerida para ayudar a responder a sus usuarios. Se presentará bajo la caja de respuestas y pueden ser copiada y pegada." + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "Puede elegir entre:
    • - área de texto (caja grande para párrafos);
    • - campo de texto (para una respuesta corta);
    • - checkboxes donde las opciones se presentan como una lista y pueden seleccionarse varios valores;
    • - botones de radio, donde se presenta una lista de opciones para elegir sólo una de ellas;
    • - lista despegable - sólo puede seleccionarse una opción;
    • - lista de selección múltiple que permite a los usuarios seleccionar varias opciones de una lista desplazable usando la tecla CTRL;
    " + +msgid "You can edit any of the details below." +msgstr "Puede editar cualquiera de los siguientes datos." + +msgid "You can not continue until you have filled in all of the required information." +msgstr "" + +#, fuzzy +msgid "You can not edit a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You can not publish a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You cannot delete historical versions of this template." +msgstr "templates" + +msgid "You have altered answers but have not saved them:" +msgstr "Ha modificado las respuestas, pero todavía no las ha grabado:" + +msgid "You have been given " +msgstr "" + +#, fuzzy +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "Organización" + +msgid "You have un-published changes" +msgstr "" + +msgid "You have unsaved answers in the following sections:" +msgstr "" + +msgid "You must accept the terms and conditions to register." +msgstr "" + +msgid "You must enter a valid email address." +msgstr "Debe introducir una dirección de correo electrónico válida." + +msgid "You need to sign in or sign up before continuing." +msgstr "" + +msgid "You now have " +msgstr "" + +msgid "Your" +msgstr "" + +msgid "Your ORCID" +msgstr "" + +msgid "Your access to " +msgstr "" + +msgid "Your account has been successfully linked to %{scheme}." +msgstr "" + +msgid "Your account won't be created until you access the link above and set your password." +msgstr "" + +msgid "Your browser does not support the video tag." +msgstr "El navegador no soporta la etiqueta video." + +msgid "Your password must contain at least 8 characters." +msgstr "Su clave ha de tener al menos 8 caracteres." + +msgid "Your permissions relating to " +msgstr "" + +#, fuzzy +msgid "Your template has been published and is now available to users." +msgstr "templates" + +#, fuzzy +msgid "Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it" +msgstr "templates" + +msgid "a day" +msgstr "" + +msgid "about %d hours" +msgstr "" + +msgid "about a minute" +msgstr "" + +msgid "about a month" +msgstr "" + +msgid "about a year" +msgstr "" + +msgid "about an hour" +msgstr "" + +msgid "account has been locked due to an excessive number of unsuccessful sign in attempts." +msgstr "" + +msgid "activerecord.errors.messages.record_invalid" +msgstr "" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.current_password.invalid" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.email.blank" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.password.blank" +msgstr "user" + +#, fuzzy +msgid "activerecord.errors.models.user.attributes.password_confirmation.confirmation" +msgstr "user" + +msgid "add guidance text" +msgstr "" + +# Timeago - found in lib/assets/javascripts/jquery.timeago.js +# --------------------- +# suffix ago +msgid "ago" +msgstr "" + +#, fuzzy +msgid "approx. %{space_used}%% of available space used (max %{num_pages} pages)" +msgstr "aprox. %{space_used}% de disponibilidad del espacio usado (máx. %{num_pages} páginas)" + +#, fuzzy +msgid "by " +msgstr " por " + +msgid "can't be blank" +msgstr "" + +msgid "can't be larger than 500KB" +msgstr "" + +msgid "can't be less than zero" +msgstr "" + +msgid "e.g. School/ Department" +msgstr "ej: Escuela / Departmento" + +#, fuzzy +msgid "example answer" +msgstr "Respuesta de ejemplo" + +msgid "from now" +msgstr "" + +#, fuzzy +msgid "generic template" +msgstr "templates" + +msgid "guidance" +msgstr "" + +#, fuzzy +msgid "guidance group" +msgstr "Grupo de orientación" + +msgid "guidance on" +msgstr "" + +msgid "height must be less than 100px" +msgstr "" + +msgid "helpers.is_test" +msgstr "" + +msgid "helpers.links.cancel" +msgstr "" + +msgid "helpers.project.is_test_help_text" +msgstr "" + +msgid "into your browser" +msgstr "" + +msgid "less than a minute" +msgstr "" + +#, fuzzy +msgid "must be logged in" +msgstr "Último acceso" + +msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" +msgstr "" + +msgid "must be unique" +msgstr "" + +#, fuzzy +msgid "must have access to guidances api" +msgstr "guidances" + +#, fuzzy +msgid "must have access to plans api" +msgstr "guidances" + +#, fuzzy +msgid "no research organisation is associated with this plan" +msgstr "Organización" + +#, fuzzy +msgid "note" +msgstr "Nota" + +msgid "or copy" +msgstr "" + +#, fuzzy +msgid "organisation" +msgstr "Organización" + +#, fuzzy +msgid "phase" +msgstr "Fase" + +#, fuzzy +msgid "plan" +msgstr "plans" + +msgid "profile" +msgstr "" + +#, fuzzy +msgid "question" +msgstr "Pregunta" + +msgid "questions answered" +msgstr "preguntas respondidas" + +#, fuzzy +msgid "role" +msgstr "Función" + +#, fuzzy +msgid "section" +msgstr "Sección" + +msgid "select a guidance group" +msgstr "" + +msgid "select at least one theme" +msgstr "" + +msgid "since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again." +msgstr "" + +#, fuzzy +msgid "template" +msgstr "templates" + +msgid "user" +msgstr "user" + +#, fuzzy +msgid "user must be in your organisation" +msgstr "Organización" diff --git a/config/locale/fr/app.po b/config/locale/fr/app.po new file mode 100644 index 0000000..26cbc38 --- /dev/null +++ b/config/locale/fr/app.po @@ -0,0 +1,1815 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the app package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: app 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2017-05-02 14:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +msgid " (UK users only)" +msgstr " (réservé aux utilisateurs britanniques)" + +msgid " - " +msgstr "" + +#, fuzzy +msgid " I accept the terms and conditions *" +msgstr " Jaccepte les Conditions générales dutilisation. *" + +#, fuzzy +msgid " Plan" +msgstr "plans" + +msgid " access to" +msgstr "" + +msgid " access. " +msgstr "" + +msgid " and " +msgstr "" + +#, fuzzy +msgid " by" +msgstr " par " + +msgid " by " +msgstr " par " + +#, fuzzy +msgid " has been removed by " +msgstr " par " + +#, fuzzy +msgid " have been changed by" +msgstr " par " + +msgid " into your browser)" +msgstr "" + +msgid " on " +msgstr "" + +msgid " or " +msgstr "" + +msgid " password. You can do this through the link below." +msgstr "" + +#, fuzzy +msgid " provided by " +msgstr " par " + +#, fuzzy +msgid " team" +msgstr "am" + +#, fuzzy +msgid " that has been customised by " +msgstr " par " + +msgid " to accept the invitation, (or copy " +msgstr "" + +msgid " will help you to develop your Data Management Plan. If you have any queries or feedback as you use the tool, please contact us on " +msgstr "" + +#, fuzzy +msgid "\"Are you sure you want to unlink #{scheme.description} ID?\"" +msgstr "Identifiant" + +msgid "\"Unlink your account from #{scheme.description}. You can link again at any time.\"" +msgstr "" + +msgid "\"Your account has been linked to #{scheme.description}.\"" +msgstr "" + +msgid "%d days" +msgstr "" + +msgid "%d minutes" +msgstr "" + +msgid "%d months" +msgstr "" + +msgid "%d years" +msgstr "" + +msgid "%{application_name}" +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} doesn't recognise your institutional credentials - either you haven't created an account with us or you haven't linked these details to your existing account.
    * If you do not have an account with %{application_name}, please complete the form below.
    * If you have an account with %{application_name}, please Sign in so we can link your account to your institutional credentials.
    Once you have created and/or linked your account, you'll be able to sign in with your institutional credentials directly." +msgstr "DMPonline" + +#, fuzzy +msgid "%{application_name} is provided by the %{organisation_name}. You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below." +msgstr "DMPonline" + +msgid "%{format} is not a valid exporting format. Available formats to export are %{available_formats}." +msgstr "" + +msgid "%{value} is not a valid format" +msgstr "" + +msgid "(Using custom PDF formatting values)" +msgstr "(Utilisation de valeurs de mise en forme PDF personnalisées)" + +msgid "(Using template PDF formatting values)" +msgstr "(Utilisation des valeurs de mise en forme PDF du modèle)" + +msgid "-" +msgstr "" + +msgid "... (continued)" +msgstr "" + +msgid "

    Questions to consider:

    • - What is the nature of your research project?
    • - What research questions are you addressing?
    • - For what purpose are the data being collected or created?

    Guidance:

    Briefly summarise the type of study (or studies) to help others understand the purposes for which the data are being collected or created.

    " +msgstr "

    Questions auxquelles réfléchir :

    • - Quelle est la nature de votre projet de recherche ?
    • - Quelles ont les problématiques de recherche que vous traitez ?
    • - Dans quel but est effectuée la collecte ou la création des données ?

    Conseils :

    Résumez brièvement le type détude(s) pour permettre à dautres de comprendre dans quel but les données sont collectées ou créées.

    " + +msgid "
    Enter a basic description. This could be a summary of what is covered in the section or instructions on how to answer. This text will be displayed in the coloured banner once a section is opened to edit.
    " +msgstr "
    Saisissez une courte description. Celle-ci peut résumer lobjet de la section ou donner des indications sur comment y répondre. Ce texte saffichera dans la bannière de couleur quand une section sera ouverte pour modification.
    " + +msgid "
    Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences.
    " +msgstr "
    Entrez une description qui permet de distinguer différents modèles, par ex. : pour des publics différents.
    " + +msgid "

    The %{organisation_name} ('%{organisation_abbreviation}') are consortia supported by %{legal_entity}. Our primary constituency is the research community, particularly the higher and further education sector.

    %{application_name}

    %{application_name} ('the tool', 'the system') is a tool developed by the %{organisation_abbreviation} as a shared resource for the research community. It is hosted by %{legal_entity}.

    Your personal details

    In order to help identify and administer your account with %{application_name}, we need to store your email address. We may also use it to contact you to obtain feedback on your use of the tool, or to inform you of the latest developments or releases. The information may be transferred between the %{organisation_abbreviation} partner institutions but only for legitimate %{organisation_abbreviation} purposes. We will not sell, rent or trade any personal information you provide to us.

    Privacy policy

    The information you enter into this system can be seen by you, people you have chosen to share access with, and - solely for the purposes of maintaining the service - system administrators at %{legal_entity}. We compile anonymised, automated and aggregated information from plans, but we will not directly access, make use of, or share your content with anyone else without your permission. Authorised officers of your home institution may access your plans for specific purposes - for example, to track compliance with funder/institutional requirements or to calculate storage requirements.

    Freedom of Information

    %{legal_entity} holds your plans on your behalf, but they are your property and responsibility. Any FOI applicants will be referred back to your home institution.

    Passwords

    Your password is stored in encrypted form and cannot be retrieved. If forgotten it has to be reset.

    Cookies

    Please note that %{application_name} uses Cookies. Further information about Cookies and how we use them is available on the main DCC website.


    Use of the tool indicates that you understand and agree to these terms and conditions.

    " +msgstr "l'outil\",\"le système" + +msgid "

    Useful resources on Data Management Planning

    Example Data Management Plans

    • Technical plan submitted to the AHRC [PDF, 7 pages]
      A DMP submitted by a researcher from the University of Bristol, also including comments from the reviewers
    • Two social science DMPs [PDF, 7 pages]
      Example plans from researchers at the University of Leeds, shared as part of the Leeds RoaDMaP training materials
    • Health sciences DMP [PDF, 11 pages]
      Example DMP produced by the DATUM for Health RDM training project
    • Psychology DMP [PDF, 11 pages]
      A very detailed, fictional psychology DMP produced by the DMTpsych RDM training project, based on a seminal psychology experiment
    • UCSD Example Data Management Plans [webpage]
      Over 20 example plans submitted to the National Science Foundation (NSF) in the United States by academics at UC San Diego
    • Colorado School of Mines examples [webpage]
      A variety of US example DMPs from Mines and elsewhere
    • NSF data management plans [webpage]
      5 DMPs submitted to the NSF, shared by the DataOne initiative
    • Biology and chemistry DMPs [webpage]
      Three example DMPs from the USA shared by NECDMC, an instructional tool for teaching RDM to undergraduates, graduate students, and researchers in the health sciences, sciences and engineering.

    Useful guides on Research Data Management in general

    • Managing and Sharing Data: best practice for researchers [PDF, 36 pages]
      A guide by the UK Data Service covering a range of topics including data formats, documentaion, ethics, copyright and data sharing.
    • How to Cite Datasets and Link to Publications [PDF, 12 pages]
      A guide by the Digital Curation Centre giving practical guidelines on how to cite data and the different tools and infrastructure that can be used to support data citation.
    • How to License Research Data [PDF, 16 pages]
      A guide by the Digital Curation Centre that outlines different types of licenses, the pros and cons of each and how they can be applied.
    • How to Appraise and Select Research Data for Curation [PDF, 8 pages]
      A guide by ANDS and the Digital Curation Centre on how to select which data to keep for long-term preservation, sharing and reuse. The guide puts forward several criteria to aid selection decisions.
    • Research Data MANTRA [online resource]
      An online training course designed for researchers or others planning to manage digital data as part of the research process. The course includes a number of software practicals on using SPSS, R, ArcGIS and NVivo.
    " +msgstr "Si vous avez besoin de plus de directives, communiquez avec nous par courriel à portage@carl-abrc.ca.

    " + +msgid "

    %{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

    " +msgstr "

    DMPonline est un développement du Digital Curation Centre (Centre de curation numérique britannique - DCC) pour vous aider dans la rédaction de plans de gestion de données, ou DMP.

    " + +msgid "

    %{application_name} is developed and maintained by the UK %{organisation_name}. We’re a small team, and are happy to collaborate with others. There are various ways you can get involved:

    Join the user group

    We run a listserv for the %{application_name} user group that you can request to join. We also host periodic meetings to consult on our plans. Being part of the user group gives you the opportunity to be informed about future developments and to provide feedback to help shape our plans.

    Our user group sessions are usually focused around a certain topic (e.g. fleshing out use cases for an API) so invites are sent based on your areas of expertise. It is helpful for us to know your role and interests to invite relevant people to each session. Please introduce yourself on the list and share your ideas.

    Notes from previous user group sessions are provided below:

    Please let us know your interests and share your ideas for future developments via the mailing list so the community as a whole can feedback on them.


    Customise %{application_name}

    %{application_name} can be customised by institutions and disciplines. You can add templates for users in your organisation and tailored guidance that explains local support and services. Example answers can also be offered to help users understand what to write in a Data Management Plan. To do this you’ll need to request admin access, so please email us on dmponline@dcc.ac.uk.

    Futher guidance on customising %{application_name} is available on the %{application_name} website.


    Contribute to the code

    %{application_name} is a Ruby on Rails application. The source code is made available under an MIT License. This permits others to reuse the code freely, but obligates you to share the source code for any extensions in the same way. Please inform us if you install an instance of %{application_name} and offer your contributions back to the community.

    If you install an instance of %{application_name} we require that you credit the %{organisation_abbreviation} as originators of the tool. We recommend that the acknowledgement takes the form of the %{application_name} logo with a link back to the %{organisation_abbreviation}-hosted version of the tool.

    We are willing to work with external developers to add new features to the tool. We are also open to delivering new features on a chargeable basis. If there are extensions you would like to see prioritised and have resource to support additional developer effort, please contact us on dmponline@dcc.ac.uk to negotiate terms.

    The code is available on GitHub

    Support our work

    We are impressed by the uptake of %{application_name} both in the UK and internationally and are really keen to hear how you are using the tool and promoting it in your context. We are aware that others have run training courses, developed guidance materials and advocated use of the tool. Please notify us of this as it helps to show impact.

    We are currently investigating options for revenue generation. This will help us serve the increased demand more effectively and safeguard the long-term sustainability of %{application_name}. Plans will be released for consultation soon but we also welcome your suggestions on how best to support our work.

    " +msgstr "" + +msgid "

    %{application_name} stories from the %{organisation_abbreviation} website


    " +msgstr "" + +msgid "

    Welcome.
    You are now ready to create your first DMP.
    Click the 'Create plan' button below to begin.

    " +msgstr "

    Bienvenue.
    Vous voilà prêt à créer votre premier DMP.
    Cliquez sur le bouton 'Créer un plan' ci-dessous pour commencer.

    " + +msgid "

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    " +msgstr "

    Commencez par créer un groupe de conseils. Celui-ci peut désigner un établissement dans son ensemble, ou un sous-ensemble : une faculté, un institut, un département. Quand vous créerez des conseils, on vous demandera de les affecter à un groupe de conseils.

    " + +msgid "

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.
    Select what format you wish to use and click to 'Export'.

    " +msgstr "

    À ce niveau, vous pouvez décharger votre plan sous différents formats. Cela peut vous être utile pour soumettre votre plan dans une demande de subvention.
    Sélectionnez votre format et cliquez sur Exporter.

    " + +msgid "

    Funding bodies increasingly require their grant-holders to produce Data Management Plans(DMP), both during the bid-preparation stage and after funding has been secured. %{application_name} has been produced by the %{organisation_name} to help research teams respond to this requirement, and any expectations that their institution or others may apply.

    The %{organisation_abbreviation} worked closely with research funders and universities to produce a tool that assists researchers to produce an effective data management plan (DMP) to cater for the whole lifecycle of a project, from bid-preparation stage through to completion.


    How the tool works

    There are a number of templates within the tool that represent the requirements of different funders and institutions. Users are asked three questions at the outset so we can determine the appropriate template to display (e.g. the ESRC template when applying for an ESRC grant). Guidance is provided to help you interpret and answer the questions. This guidance is provided by researcher funders, universities and disciplines.


    Getting Started

    If you have an account please sign in and start creating or editing your DMP.

    If you do not have a %{application_name} account, click on 'Create account' on the homepage.

    Please visit the 'Help' page for guidance.


    Additional Information

    We are constantly improving the user interface and functionality of %{application_name}. If you would like to contribute with feedback and suggestions, please contact us by emailing dmponline@dcc.ac.uk. You can also report bugs and request new features directly on GitHub

    " +msgstr "" + +msgid "

    Here you can view previously published versions of your template. These can no longer be modified.

    " +msgstr "" + +msgid "

    Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

    " +msgstr "

    Vous définissez ici le titre que verrons les utilisateurs. Si vous souhaitez que votre DMP comporte plusieurs phases, cela doit apparaître clairement dans le titre et la description.

    " + +msgid "

    If you wish to add an institutional template for a Data Management Plan, use the 'create template' button. You can create more than one template if desired e.g. one for researchers and one for PhD students.

    Your template will be presented to users within your institution when no funder templates apply. If you want to add questions to funder templates use the 'customise template' options below.

    " +msgstr "

    Si vous souhaitez ajouter un modèle institutionnel propre à un plan de gestion de données, utilisez le bouton créer un modèle. Vous pouvez au besoin créer plusieurs modèles, par ex. : un pour des chercheurs et un pour des thésards.

    Votre modèle apparaîtra aux utilisateurs de votre établissement quand aucun modèle propre à un bailleur de subvention ne sapplique. Si vous souhaitez ajouter des questions dans un modèle de bailleur de subventions, utilisez les options de personalisation de modèle ci-après.

    " + +msgid "

    Select themes that are relevant to this question.

    This allows your generic institution-level guidance to be drawn in, as well as that from other sources e.g. the %{organisation_abbreviation} or any Schools/Departments that you provide guidance for.

    You can select multiple themes by using the CTRL button.

    " +msgstr "

    Sélectionnez les thèmes relatifs à cette question.

    Cette fonction permet dintégrer une documentation générale dassistance de votre établissement, comme encore issue dautres sources comme le DCC et des facultés ou départements auxquels vous fournissez des conseils.

    Vous pouvez sélectionner plusieurs thèmes avec la touche CTRL.

    " + +msgid "

    The %{organisation_abbreviation} are now collaborating to develop a joint codebase for Data Management Planning called DMP Roadmap. Both of our tools will be delivered using this in the future. We've agreed what features need to be included and are planning a few sprints to deliver these. The initial release will include all of the main priorities we already had flagged, including:

    • - APIs to create plans, extract guidance and generate statistics from %{application_name}
    • - Multi-lingual support so foreign language versions can be presented
    • - Locales to provide a refined set of content for particular countries or other contexts
    • - A lifecycle to indicate the status of DMPs and allow institutional access to plans
    • - Support for reviewing Data Management Plans

    %{application_name} has an active and growing user base, and we are grateful to the members who suggest ideas for new and improved features. If you would like to help shape our future plans, please join the user group. More information on how you can engage with us is available under the 'Get involved' tab.


    Current release

    The current version of %{application_name} is %{application_version}.

    The code is available on GitHub


    " +msgstr "" + +msgid "

    The table below lists the plans that you have created, and any that have been shared with you by others.
    These can be edited, shared, exported or deleted at anytime.

    " +msgstr "

    Dans le tableau ci-dessous figurent les plans que vous avez créés, ainsi que ceux que vous partagez avec d'autres.
    Vous pouvez à tout moment les modifier, les partager, les exporter, les effacer...

    " + +msgid "

    To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.

    " +msgstr "

    Pour créer un nouveau modèle, commencez par saisir un titre et une description. Un fois ces éléments enregistrés, le programme vous propose dajouter une phase ou plus.

    " + +msgid "

    When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    Create a plan

    To create a plan, click the 'Create plan' button from the 'My plans' page or the top menu. Select options from the drop-down menus and tickboxes to determine what questions and guidance you should be presented with. Confirm your selection by clicking 'Yes, create plan'

    Write your plan

    The tabbed interface allows you to navigate through different functions when editing your plan.

    • - 'Plan details' includes basic administrative details, tells you what sets of questions and guidance your plan is based on and gives you an overview to the questions that you will be asked.
    • - The following tab(s) present the questions to answer. There may be more than one tab if your funder or university asks different sets of questions at different stages e.g. at grant application and post-award.
    • - The 'Share' tab allows you to invite others to read or contribute to your plan.
    • - The 'Export' tab allows you to download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application.

    When viewing any of the question tabs, you will see the different sections of your plan displayed. Click into these in turn to answer the questions. You can format your responses using the text editing buttons.

    Guidance is displayed in the right-hand panel. Click the '+' symbol to view this.

    Remember to 'save' your responses before moving on.

    Share plans

    Insert the email address of any collaborators you would like to invite to read or edit your plan. Set the level of permissions you would like to grant them via the drop-down options and click to 'Add collaborator'

    Export plans

    From here you can download your plan in various formats. This may be useful if you need to submit your plan as part of a grant application. Choose what format you would like to view/download your plan in and click to export. When you login to %{application_name} you will be directed to the 'My plans' page. From here you can edit, share, export or delete any of your plans. You will also see plans that have been shared with you by others.

    " +msgstr "

    Lorsque vous vous connectez à l'Assistant PGD, vous serez dirigé vers la page « Mes plans ». À partir de cette page, vous pouvez modifier, partager, exporter ou supprimer l'un ou l'autre de vos plans. Vous verrez également les plans qui ont été partagés avec vous par d'autres personnes.

    Créer un plan

    Pour créer un plan, cliquez sur le bouton « Créer un plan » à la page « Mes plans » ou dans le menu du haut. Faites des choix dans les listes déroulantes et les cases à cocher afin de déterminer les questions et les directives qui seront affichées. Confirmez votre choix en cliquant sur « Oui, créer un plan ».

    Rédiger votre plan

    L'interface à onglets vous permet de naviguer dans diverses fonctions lorsque vous mettez au point votre plan.

    • - L'option « renseignements sur le plan » comprend des renseignements administratifs de base, indique la série de questions et de directives sur laquelle votre plan s'appuie et vous donne un aperçu des questions auxquelles vous devez répondre.
    • - Les onglets suivants contiennent les questions auxquelles il faut répondre. Il peut y avoir plus d'un onglet si votre bailleur de fonds ou votre université pose différentes séries de questions à diverses étapes, par exemple lors d'une demande de subvention et après l'octroi d'une subvention.
    • - L'onglet « Partager » vous permet d'inviter d'autres personnes à lire votre plan ou à y collaborer.
    • - L'onglet « Exporter » vous permet de télécharger votre plan en divers formats, ce qui peut être utile si vous devez joindre votre plan à une demande de subvention.

    Lorsque vous consultez l'un ou l'autre des onglets de questions, vous verrez les différentes sections de votre plan affichées. Cliquez sur ces onglets à tour de rôle pour répondre aux questions. Vous pouvez choisir le format de vos réponses à l'aide des boutons de mise en forme.

    Les directives sont affichées dans la partie de droite. Cliquez sur le symbole « + » pour les consulter.

    N'oubliez pas d'enregistrer vos réponses avant de poursuivre.

    Partager les plans

    Inscrivez l'adresse électronique de tout collaborateur que vous aimeriez inviter à lire ou à modifier votre plan. Choisissez le niveau d'autorisation que vous souhaitez lui accorder dans les options de la liste déroulante et cliquez sur « Ajouter un collaborateur ».

    Exporter les plans

    En choisissant cette option, vous pouvez télécharger votre plan en divers formats, ce qui peut être utile si vous devez joindre votre plan à une demande de subvention. Choisissez le format dans lequel vous aimeriez voir ou télécharger votre plan et cliquez pour l'exporter. Lorsque vous vous connectez à l'Assistant PGD, vous êtes dirigé vers la page « Mes plans ». À partir de cette page, vous pouvez modifier, partager, exporter ou supprimer l'un ou l'autre de vos plans. Vous voyez également les plans qui ont été partagés avec vous par d'autres personnes.

    " + +msgid "

    You are about to unlink %{application_name} of your institutional credentials, would you like to continue?

    " +msgstr "

    Vous allez détacher DMPonline de votre authentfiant détablissement, voulez-vous continuer ?

    " + +#, fuzzy +msgid "

    You can give other people access to your plan here. There are three permission levels.

    • Users with \"read only\" access can only read the plan.
    • Editors can contribute to the plan.
    • Co-owners can also contribute to the plan, but additionally can edit the plan details and control access to the plan.

    Add each collaborator in turn by entering their email address below, choosing a permission level and clicking \"Add collaborator\".

    Those you invite will receive an email notification that they have access to this plan, inviting them to register with %{application_name} if they don't already have an account. A notification is also issued when a user's permission level is changed.

    " +msgstr "

    À ce niveau, vous pouvez donner accès à votre plan à dautres personnes. Trois niveaux dautorisation sont possibles.

    • Les utilisateurs avec un droit en \"lecture seule\" ne pourront que consulter le plan.
    • Les utilisateurs avec un droit de mofification pourront y contribuer.
    • Les copropriétaires le peuvent aussi, mais peuvent aussi en modifier les détails et en contrôler laccès.

    Ajoutez chacun des collaborateurs en saisissant leurs courriels lun après lautre, en choisissant un niveau dautorisation et en cliquant sur \"Ajouter le collaborateur\".

    Ceux qui sont invités recevront un avis par courriel leur indiquant quils ont accès à ce plan, invitant ceux qui nont pas de compte dans DMPonline à senregistrer. Lutilisateur reçoit aussi un avis quand ces droits sont changés.

    " + +#, fuzzy +msgid "

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board). Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    If you do have a need to provide guidance for specific funders that would not be useful to a wider audience (e.g. if you have specific instructions for applicants to BBSRC for example), you can do so by adding guidance to a specific question when you edit your template.

    " +msgstr "templates" + +#, fuzzy +msgid "" +"
    • %{organisation_name}
    • \n" +"
    • %{organisation_address_line1}
    • \n" +"
    • %{organisation_address_line2}
    • \n" +"
    • %{organisation_address_line3}
    • \n" +"
    • %{organisation_address_line4}
    • \n" +"
    • %{organisation_address_country}
    • \n" +"
    \n" +"

    Helpline: %{organisation_telephone}

    \n" +"

    Email %{organisation_email}

    " +msgstr "DMPonline" + +#, fuzzy +msgid "A Data Management Plan in %{application_name} has been shared with you" +msgstr "DMPonline" + +msgid "A colleague has invited you to contribute to their Data Management Plan at " +msgstr "" + +msgid "A pertinent ID as determined by the funder and/or institution." +msgstr "Un identifiant approprié conforme aux prescriptions de lorganisme financeur ou de létablissement." + +msgid "A required setting has not been provided" +msgstr "Vous navez pas précisé un réglage obligatoire" + +msgid "A version of " +msgstr "" + +msgid "API Information" +msgstr "" + +msgid "API rights" +msgstr "" + +msgid "API token" +msgstr "" + +msgid "Abbreviation" +msgstr "Abréviation" + +msgid "About" +msgstr "À propos..." + +msgid "About %{application_name}" +msgstr "À propos de l'Assistant PGD" + +msgid "Access removed" +msgstr "" + +msgid "Actions" +msgstr "Actions" + +msgid "Add Annotations" +msgstr "" + +#, fuzzy +msgid "Add an appropriate name for your guidance group. This name will be used to tell the end user where the guidance has come from. It will be appended to text identifying the theme e.g. \"[guidance group name]: guidance on data sharing\" so we suggest you just use the institution or department name." +msgstr "Groupe de conseils" + +msgid "Add collaborator" +msgstr "Ajouter le collaborateur" + +msgid "Add guidance" +msgstr "Ajoutez des conseils" + +msgid "Add guidance group" +msgstr "Ajoutez un groupe de conseils" + +msgid "Add new phase +" +msgstr "Ajouter une nouvelle phase +" + +msgid "Add note" +msgstr "Ajouter une note" + +msgid "Add option" +msgstr "Ajoutez une option" + +msgid "Add question" +msgstr "Ajouter une question" + +msgid "Add section" +msgstr "Ajouter une section" + +msgid "Additional comment area will be displayed." +msgstr "" + +msgid "Admin Details" +msgstr "" + +msgid "Admin area" +msgstr "Administration" + +msgid "All the best," +msgstr "" + +#, fuzzy +msgid "Allows the user to amend the organisation details (name, URL etc) and add basic branding such as the logo" +msgstr "Organisation" + +#, fuzzy +msgid "Allows the user to assign permissions to other users within the same organisation. Users can only assign permissions they own themselves" +msgstr "Organisation" + +#, fuzzy +msgid "Allows the user to create and edit guidance" +msgstr "user" + +#, fuzzy +msgid "Allows the user to create new institutional templates, edit existing ones and customise funder templates" +msgstr "templates" + +msgid "An error has occurred while saving/resetting your export settings." +msgstr "" + +msgid "Annotations" +msgstr "" + +#, fuzzy +msgid "Answer" +msgstr "Réponses" + +msgid "Answer format" +msgstr "Format de réponse" + +msgid "Answer questions" +msgstr "Répondez aux questions" + +#, fuzzy +msgid "Answered" +msgstr "Réponse " + +#, fuzzy +msgid "Answered at" +msgstr "Réponse " + +#, fuzzy +msgid "Answered by" +msgstr "Réponse " + +msgid "Answers" +msgstr "Réponses" + +msgid "Anything you enter here will display in the answer box. If you want an answer in a certain format (e.g. tables), you can enter that style here." +msgstr "Tout ce que vous écrivez saffiche dans la boîte de réponse. Si vous souhaitez une réponse ayant une certaine forme (par ex. : des tableaux), cest ici que vous pouvez entrer ce style." + +#, fuzzy +msgid "Are you sure you want to remove this note?" +msgstr "Êtes-vous sûr de vouloir retirer cette note?" + +msgid "Are you sure you wish to delete this plan? If the plan is being shared with other users, by deleting it from your list, the plan will be deleted from their plan list as well" +msgstr "Voulez-vous vraiment effacer ce plan ? S'il est partagé avec d'autres utilisateurs, le fait de l'effacer de votre liste, l'effacera aussi de leur liste de plans." + +msgid "Are you sure?" +msgstr "Êtes-vous sûr ?" + +msgid "Back" +msgstr "Retour" + +msgid "Back to edit view" +msgstr "Retour à la vue à modifier" + +msgid "Background" +msgstr "Assistant PGD" + +msgid "Bad Credentials" +msgstr "" + +msgid "Bad Parameters" +msgstr "" + +msgid "Before submitting, please consider:" +msgstr "" + +#, fuzzy +msgid "Before you get started, we need to ask a few questions to set you up with the best DMP template for your needs." +msgstr "Questions" + +msgid "Begin typing to see a filtered list" +msgstr "" + +msgid "Below is a list of users registered for your organisation. You can sort the data by each field." +msgstr "La liste ci-dessous indique les utilisateurs de votre organisme. Ces informations peuvent être triées par champ." + +msgid "Bottom" +msgstr "Bas" + +msgid "By " +msgstr "" + +msgid "Cancel" +msgstr "Annuler" + +#, fuzzy +msgid "Cannot share plan with %{email} since that email matches with the owner of the plan." +msgstr "plans" + +msgid "Change language" +msgstr "" + +msgid "Change my password" +msgstr "" + +#, fuzzy +msgid "Change organisation details" +msgstr "Organisation" + +msgid "Check box" +msgstr "Case à cocher" + +msgid "Check this box when you are ready for this guidance to appear on user's plans." +msgstr "" + +msgid "Click here" +msgstr "" + +msgid "Click here to accept the invitation" +msgstr "" + +msgid "Click here to confirm your account" +msgstr "" + +msgid "Click the link below to unlock your account" +msgstr "" + +msgid "Co-owner" +msgstr "Copropriétaire" + +msgid "Collaborators" +msgstr "Collaborateurs" + +msgid "Comment" +msgstr "Commentaire" + +#, fuzzy +msgid "Comment removed." +msgstr "Commentaire" + +msgid "Comment was successfully created." +msgstr "" + +#, fuzzy +msgid "Comment was successfully saved." +msgstr "Création du plan effectuée." + +msgid "Contact Email" +msgstr "" + +#, fuzzy +msgid "Contact Us" +msgstr "Communiquez avec nous" + +msgid "Contact us" +msgstr "Communiquez avec nous" + +msgid "Create a new plan" +msgstr "Créer un nouveau plan" + +msgid "Create a template" +msgstr "Créer un modèle" + +msgid "Create account" +msgstr "Sinscrire" + +msgid "Create plan" +msgstr "Create plan" + +msgid "Created" +msgstr "Créé" + +msgid "Created at" +msgstr "Créée à" + +msgid "Current password" +msgstr "" + +msgid "Customise" +msgstr "Personnaliser" + +msgid "Default" +msgstr "Par défaut" + +msgid "Default answer" +msgstr "Réponse par défaut" + +msgid "Default value" +msgstr "Valeur par défaut" + +msgid "Delete" +msgstr "Effacer" + +#, fuzzy +msgid "Delete Example Answer" +msgstr "Exemple de réponse" + +msgid "Delete question" +msgstr "Supprimer la question" + +msgid "Description" +msgstr "" + +msgid "Details" +msgstr "Détails" + +msgid "Details successfully updated." +msgstr "" + +msgid "Didn't receive confirmation instructions?" +msgstr "Instructions de confirmation non reçues ?" + +msgid "Didn't receive unlock instructions?" +msgstr "Instructions de déverrouillage non reçues ?" + +msgid "Discard" +msgstr "Rejeter" + +msgid "Display additional comment area." +msgstr "" + +msgid "Draft" +msgstr "" + +msgid "Dropdown" +msgstr "Liste déroulante" + +msgid "E.g ORCID http://orcid.org/." +msgstr "par ex. : ORCID http://orcid.org/." + +msgid "Edit" +msgstr "Modifier" + +#, fuzzy +msgid "Edit Annotations" +msgstr "Modifier" + +msgid "Edit User Privileges" +msgstr "" + +msgid "Edit customisation" +msgstr "Modifier la personnalisation" + +msgid "Edit phase" +msgstr "Modifier la phase" + +msgid "Edit phase details" +msgstr "Modifiez les détails de la phase" + +msgid "Edit plan details" +msgstr "Modifier des détails du plan" + +msgid "Edit profile" +msgstr "Modifier le profil" + +msgid "Edit question" +msgstr "Modifier la question" + +msgid "Edit template details" +msgstr "Modifier les détails du modèle" + +#, fuzzy +msgid "Editor" +msgstr "Modifier" + +msgid "Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access." +msgstr "Les collaborateurs avec des droits de modification peuvent contribuer aux plans. Les copropriétaires ont en plus le droit de modifier les détails du plan et en contrôler laccès. " + +msgid "Email" +msgstr "Courriel" + +msgid "Email address" +msgstr "Adresse courriel" + +msgid "Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer." +msgstr "Entrez une courte description. Les utilisateurs la verront au-dessus du récapitulaif des parties et des questions auxquels ils devront répondre." + +msgid "Enter a description that helps you to differentiate between templates e.g. if you have ones for different audiences" +msgstr "Saisissez une description qui vous permet de distinguer un modèle de lautre, par ex. : si vous visez différents" + +msgid "Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP" +msgstr "Saisissez une titre pour cette phase, par ex. : DMP initial, DMP complet... Ce sont ces mentions que verrons les utilisateurs dans les onglets pendant la rédaction dun plan. Si le vôtre ne comporte quune phase, donnez-lui un nom général, par ex. : DMP de Glasgow" + +msgid "Enter any options that you wish to display. If you want to pre-set one option as selected, check the default box." +msgstr "Saisissez toutes les options que vous voulez afficher. Si vous voulez paramétrer la sélection par défaut dun élément, cochez la case correspondante." + +msgid "Enter specific guidance to accompany this question. If you have guidance by themes too, this will be pulled in based on your selections below so it's best not to duplicate too much text." +msgstr "Saisissez des instructions spécifiques pour accompagner cette question. Si vous avez des conseils par thèmes aussi : ceux-ci vont être aiguillés ici selon ce que sélectionnez ci-dessous, aussi mieux vaut éviter de dupliquer trop dextraits." + +msgid "Enter your guidance here. You can include links where needed." +msgstr "Entrez ici vos conseils. Vous pouvez ajouter des liens là où il faut." + +msgid "Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long." +msgstr "" + +msgid "Error!" +msgstr "Erreur!" + +#, fuzzy +msgid "Example Answer" +msgstr "Exemple de réponse" + +#, fuzzy +msgid "Example of answer" +msgstr "Exemple de réponse" + +msgid "Export" +msgstr "Exporter" + +#, fuzzy +msgid "Export settings updated successfully." +msgstr "Exporter" + +#, fuzzy +msgid "Exporting public plan is under development. Apologies for any inconvience." +msgstr "Exporter" + +msgid "Face" +msgstr "Police" + +msgid "File Name" +msgstr "Titre du plan" + +msgid "Fill in the required fields" +msgstr "" + +msgid "Filter plans" +msgstr "Filtrer les plans" + +msgid "First name" +msgstr "Prénom" + +msgid "Font" +msgstr "" + +msgid "Forgot your password?" +msgstr "" + +msgid "Format" +msgstr "" + +msgid "Funder" +msgstr "Funder" + +msgid "Funders templates" +msgstr "Modèles des bailleurs de subventions" + +#, fuzzy +msgid "Funding organisation" +msgstr "Organisation" + +msgid "Future plans" +msgstr "" + +msgid "Get involved" +msgstr "" + +msgid "Grant number" +msgstr "Titre de la subvention" + +msgid "Grant permissions" +msgstr "" + +msgid "Grant reference number if applicable [POST-AWARD DMPs ONLY]" +msgstr "N° de réféence de la subvention, le cas échéant (UNIQUEMENT POUR LES DMP CRÉÉS APRÈS OCTROI DUNE SUBVENTION)" + +msgid "Guidance" +msgstr "Conseils" + +#, fuzzy +msgid "Guidance choices saved." +msgstr "Conseils" + +msgid "Guidance group" +msgstr "Groupe de conseils" + +msgid "Guidance group list" +msgstr "Liste des groupes de conseils" + +msgid "Guidance group was successfully created." +msgstr "Création du groupe de conseils effectuée." + +msgid "Guidance group was successfully deleted." +msgstr "Suppression du groupe de conseils effectuée." + +msgid "Guidance group was successfully updated." +msgstr "Mise à jour du groupe de conseils effectuée." + +msgid "Guidance list" +msgstr "Liste de conseils" + +msgid "Guidance was successfully created." +msgstr "Création de conseils effectuée." + +#, fuzzy +msgid "Guidance was successfully deleted." +msgstr "Création de conseils effectuée." + +msgid "Guidance was successfully updated." +msgstr "Mise à jour de conseils effectuée." + +msgid "Hello" +msgstr "" + +msgid "Hello " +msgstr "" + +msgid "Help" +msgstr "Aide" + +msgid "History" +msgstr "" + +msgid "Home" +msgstr "Accueil" + +msgid "How many plans?" +msgstr "Nombre de plans?" + +msgid "How to use the API" +msgstr "" + +msgid "ID" +msgstr "Identifiant" + +msgid "If applying for funding, state the name exactly as in the grant proposal." +msgstr "En cas de demande de financement, indiquer le nom exactement comme dans la demande de subvention." + +#, fuzzy +msgid "If applying for funding, state the title exactly as in the proposal." +msgstr "En cas de demande de financement, indiquer le nom exactement comme dans la demande de subvention." + +msgid "If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard." +msgstr "Si les conseils ne sont destinés quà un sous-ensemble dutilisateurs (par ex. : faisant partie dune faculté ou dun institut), cochez cette case. Les utilisateurs pourront sélectionner ce sous-groupe de conseils lorquils répondront aux questions dans lassistant de création de plan." + +msgid "If you are entering an URL try to use something like http://tinyurl.com/ to make it smaller." +msgstr "" + +msgid "If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo." +msgstr "" + +msgid "If you didn't request this, please ignore this email." +msgstr "" + +msgid "If you don't want to accept the invitation, please ignore this email." +msgstr "" + +msgid "If you would like to change your password please complete the following fields." +msgstr "" + +msgid "Included Elements" +msgstr "Éléments inclus" + +msgid "Information was successfully created." +msgstr "Création des informations effectuée." + +msgid "Information was successfully deleted." +msgstr "Suppression des informations effectuée." + +msgid "Information was successfully updated." +msgstr "Mise à jour des informations effectuée." + +msgid "Institution" +msgstr "Institution" + +msgid "Invalid font face" +msgstr "Police non valide" + +msgid "Invalid font size" +msgstr "Taille de police non valide" + +msgid "Invalid maximum pages" +msgstr "Nombre de pages maxi non valide" + +msgid "Invitation to %{email} issued successfully." +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Last logged in" +msgstr "Dernière connexion" + +msgid "Last name" +msgstr "Nom" + +msgid "Last updated" +msgstr "Dernière m.à j." + +msgid "Latest news" +msgstr "Modèle de plan de gestion des données Portage" + +msgid "Left" +msgstr "Gauche" + +msgid "List of users" +msgstr "Liste des utilisateurs" + +msgid "Logo" +msgstr "" + +msgid "Main organisation" +msgstr "Organisme principal" + +msgid "Many thanks," +msgstr "" + +msgid "Margin" +msgstr "Marge" + +msgid "Margin cannot be negative" +msgstr "Une marge ne peut être négative" + +msgid "Margin value is invalid" +msgstr "Valeur de marge non valide" + +msgid "Me" +msgstr "Moi" + +#, fuzzy +msgid "Message" +msgstr "Moi" + +#, fuzzy +msgid "Modify guidance" +msgstr "Ajoutez des conseils" + +#, fuzzy +msgid "Modify templates" +msgstr "templates" + +msgid "Multi select box" +msgstr "Boîte de sélections multiples" + +#, fuzzy +msgid "My Plan" +msgstr "Mon plan" + +msgid "My organisation isn't listed." +msgstr "Mon établissement nest pas listé." + +msgid "My plans" +msgstr "Mes plans" + +#, fuzzy +msgid "My research organisation is not on the list" +msgstr "Organisation" + +msgid "Name" +msgstr "Prénom" + +msgid "Name (if different to above), telephone and email contact details" +msgstr "Nom (sil diffère du précédent), coordonnées courriel et téléphone" + +msgid "Name of Principal Investigator(s) or main researcher(s) on the project." +msgstr "Nom du ou des directeurs de recherche ou du ou des principaux chercheurs du projet." + +msgid "New guidance" +msgstr "Nouveaux conseils" + +msgid "New password" +msgstr "" + +msgid "New section title" +msgstr "Le nouveau titre de section" + +msgid "New template" +msgstr "Nouveau modèle" + +msgid "New to %{application_name}? Create an account today." +msgstr "Nouveau sur DMPonline ? Inscrivez-vous..." + +msgid "No" +msgstr "" + +msgid "No additional comment area will be displayed." +msgstr "" + +#, fuzzy +msgid "No funder associated with this plan" +msgstr "plans" + +msgid "No items available." +msgstr "" + +msgid "No matches" +msgstr "Pas de plans pour %{filter}" + +msgid "None" +msgstr "Aucun" + +msgid "Not answered yet" +msgstr "Pas encore de réponse" + +msgid "Note" +msgstr "Note" + +msgid "Note removed by" +msgstr "Note retirée par" + +msgid "Note removed by you" +msgstr "Note retirée par vous" + +msgid "Noted by:" +msgstr "Note par :" + +msgid "Ok" +msgstr "" + +msgid "On %{application_name}" +msgstr "Concernant l'Assistant PGD" + +msgid "On data management planning" +msgstr "Concernant la planification de la gestion des données" + +msgid "Optional subset" +msgstr "Sous-ensemble facultatif" + +msgid "Or, sign in with your institutional credentials" +msgstr "ou, connectez-vous avec votre authentifiant détablissement" + +msgid "Order" +msgstr "Ordre" + +msgid "Order of display" +msgstr "Ordre daffichage" + +msgid "Organisation" +msgstr "Organisation" + +msgid "Organisation details" +msgstr "Détails sur lorganisme" + +msgid "Organisation name" +msgstr "Nom de lorganisme" + +msgid "Organisation type" +msgstr "Type dorganisme" + +msgid "Organisation was successfully updated." +msgstr "Mise à jour de lorganisme effectuée." + +msgid "Organisational" +msgstr "Organisationnel" + +msgid "Organisational (visibile to others within your organisation)" +msgstr "Avec d'autres membres de votre organisation" + +msgid "Organization" +msgstr "Organisation" + +#, fuzzy +msgid "Original funder template has changed!" +msgstr "templates" + +msgid "Other institutions" +msgstr "" + +msgid "Own templates" +msgstr "Modèles propres" + +msgid "Owner" +msgstr "Propriétaire" + +msgid "PDF Formatting" +msgstr "Mise en forme PDF" + +msgid "Password" +msgstr "" + +msgid "Password and comfirmation must match" +msgstr "" + +msgid "Password confirmation" +msgstr "" + +msgid "Permissions" +msgstr "Permissions" + +msgid "Phase details" +msgstr "Détails de la phase" + +msgid "Plan Data Contact" +msgstr "Interlocuteur pour les données du plan" + +msgid "Plan Description" +msgstr "Description" + +msgid "Plan ID" +msgstr "Identifiant du projet" + +msgid "Plan Name" +msgstr "Nom du projet" + +msgid "Plan data contact" +msgstr "Interlocuteur pour les données du plan" + +msgid "Plan details" +msgstr "Détails du plan" + +msgid "Plan is already shared with %{email}." +msgstr "" + +msgid "Plan name" +msgstr "Nom du plan" + +msgid "Plan shared with %{email}." +msgstr "" + +#, fuzzy +msgid "Plan was successfully deleted." +msgstr "Création du plan effectuée." + +msgid "Plan was successfully updated." +msgstr "" + +msgid "Please add an abbreviation to your org for display with annotations!" +msgstr "" + +#, fuzzy +msgid "Please enter a First name." +msgstr "Entrez votre prénom, svp." + +#, fuzzy +msgid "Please enter a Last name." +msgstr "Entrez votre prénom, svp." + +msgid "Please enter a password confirmation" +msgstr "" + +msgid "Please enter a title for your template." +msgstr "Merci de saisir un titre pour votre modèle." + +msgid "Please enter a valid web address." +msgstr "Formation à la rédaction de documents scientifiques en anglais une adresse web valide." + +msgid "Please enter an email address" +msgstr "" + +#, fuzzy +msgid "Please enter an email address." +msgstr "Formation à la rédaction de documents scientifiques en anglais une adresse web valide." + +msgid "Please enter the name of your organisation." +msgstr "Veuillez saisir le nom de votre organisme.." + +msgid "Please enter your current password" +msgstr "" + +msgid "Please enter your current password below when changing your email address." +msgstr "" + +msgid "Please enter your email" +msgstr "" + +msgid "Please enter your first name." +msgstr "Entrez votre prénom, svp." + +msgid "Please enter your organisation's name." +msgstr "Entrez le nom de votre organisme." + +msgid "Please enter your password to change email address." +msgstr "" + +msgid "Please enter your surname or family name." +msgstr "Entrez votre nom dusage ou de famille, svp." + +msgid "Please fill in the basic project details below" +msgstr "" + +msgid "Please fill in the basic project details below and click 'Update' to save" +msgstr "Veuillez renseigner les premiers détails ci-après et cliquez sur 'Mettre à jour' pour enregistrer" + +#, fuzzy +msgid "Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in." +msgstr "

    À noter que votre courriel est à utiliser comme nom dutilisateur. Si vous modifiez ces informations, rappelez-vous dutiliser votre courriel en vous connectant.

    " + +msgid "Please only enter up to 165 characters, you have used" +msgstr "" + +#, fuzzy +msgid "Please select an organisation, or select Other." +msgstr "Organisation" + +msgid "Please select one" +msgstr "" + +msgid "Preview" +msgstr "Aperçu" + +#, fuzzy +msgid "Primary research organisation" +msgstr "Organisation" + +msgid "Principal Investigator / Researcher" +msgstr "Directeur de recherche / chercheur" + +msgid "Principal Investigator/Researcher" +msgstr "Directeur de recherche/Chercheur" + +msgid "Principal Investigator/Researcher ID" +msgstr "Identifiant du directeur de recherche/chercheur" + +msgid "Private" +msgstr "Privé" + +msgid "Private (owners, co-owners, and administrators only) See our Terms of Use." +msgstr "Privé (propriétaires, copropriétaires et administrateurs uniquement) Consultez nos Conditions d'utilisation." + +msgid "Privileges" +msgstr "" + +msgid "Project title" +msgstr "" + +#, fuzzy +msgid "Provides the user with an API token and grants rights to harvest information from the tool" +msgstr "user" + +msgid "Public" +msgstr "Public" + +msgid "Public (Your DMP will appear on the Public DMPs page of this site)" +msgstr "Publiquement sur le web. Votre DMP apparaîtra sur la page Public DMPs de ce site." + +msgid "Public DMPs" +msgstr "DMP publics" + +msgid "Public DMPs are plans created using the DMPTool and shared publicly by their owners. They are not vetted for quality, completeness, or adherence to funder guidelines." +msgstr "Les DMP publics sont des plans créés à l'aide de DMPTool et partagés publiquement par leurs propriétaires. Ils ne sont pas vérifiés pour la qualité, l'exhaustivité ou l'adhésion aux lignes directrices des bailleurs de fonds." + +msgid "Publish" +msgstr "" + +msgid "Publish changes" +msgstr "" + +msgid "Published" +msgstr "Publiée" + +msgid "Question" +msgstr "Question" + +msgid "Question not answered" +msgstr "Question sans réponse." + +msgid "Question not answered." +msgstr "Question sans réponse." + +msgid "Question number" +msgstr "Numéro de la question" + +msgid "Question text" +msgstr "Texte de la question" + +msgid "Question text is empty, please enter your question." +msgstr "" + +msgid "Questions" +msgstr "Questions" + +msgid "Radio buttons" +msgstr "Boutons radio" + +msgid "Read more on the " +msgstr "" + +msgid "Read only" +msgstr "Lecture seule" + +msgid "Releases" +msgstr "" + +msgid "Remember me" +msgstr "Se souvenir de moi" + +msgid "Remove" +msgstr "Retirer" + +msgid "Remove user access" +msgstr "Retirer laccès utilisateur" + +msgid "Reset" +msgstr "Réinitialiser" + +msgid "Right" +msgstr "Droite" + +msgid "Save" +msgstr "Enregistrer" + +#, fuzzy +msgid "Save Unsuccessful." +msgstr "Enregistrer" + +msgid "Saving..." +msgstr "Enregistrement en cours..." + +msgid "Screencast on how to use %{application_name}" +msgstr "Vidéo en ligne sur lutilisation de DMPonline" + +msgid "Section" +msgstr "Section" + +msgid "Sections" +msgstr "Sections" + +#, fuzzy +msgid "Select a template" +msgstr "templates" + +msgid "Select an action" +msgstr "Sélectionnez une action" + +#, fuzzy +msgid "Select the funding organisation" +msgstr "Organisation" + +#, fuzzy +msgid "Select the primary research organisation responsible" +msgstr "Organisation" + +msgid "Select which group this guidance relates to." +msgstr "Sélectionnez le groupe auxquel ces conseils sont liés." + +msgid "Select which theme(s) this guidance relates to." +msgstr "Sélectionnez le ou les thèmes liés à ces conseils." + +msgid "Selected option(s)" +msgstr "" + +msgid "Share" +msgstr "Partager" + +msgid "Share note" +msgstr "Partager la note" + +msgid "Share note with collaborators" +msgstr "Partager la note avec des collaborateurs" + +msgid "Sharing details successfully updated." +msgstr "" + +msgid "Should this guidance apply:" +msgstr "Si ces conseils sappliquent :" + +msgid "Sign in" +msgstr "Connexion" + +msgid "Sign out" +msgstr "Déconnexion" + +msgid "Signed in as " +msgstr "Connecté en tant que " + +msgid "Size" +msgstr "Taille" + +msgid "Someone has requested a link to change your " +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Subject" +msgstr "" + +msgid "Successfully unlinked your account from %{is}." +msgstr "" + +msgid "Suggested answer" +msgstr "Suggestion de réponse" + +msgid "Suggested answer/ Example" +msgstr "Suggestion/exemple de réponse" + +msgid "Super admin area" +msgstr "Espace Super admin" + +msgid "Template" +msgstr "Template" + +msgid "Template History" +msgstr "" + +msgid "Template details" +msgstr "Détails du modèle" + +msgid "Templates" +msgstr "Modèles" + +msgid "Terms of use" +msgstr "Exploitation sous licence et conditions d'utilisation" + +msgid "Test/Practice" +msgstr "Test/Pratique" + +msgid "Test/Practice (your plan is not visible to other users) See our Terms of Use." +msgstr "Test / Practice (votre plan n'est pas visible aux autres utilisateurs) Voir nos Conditions d'utilisation." + +msgid "Text" +msgstr "Texte" + +msgid "Text area" +msgstr "Zone de texte" + +msgid "Text field" +msgstr "Champ textuel" + +msgid "Thank you for registering. Please confirm your email address" +msgstr "" + +msgid "That email address is already registered." +msgstr "" + +#, fuzzy +msgid "That template is not currently published." +msgstr "templates" + +msgid "The" +msgstr "" + +msgid "The " +msgstr "" + +msgid "The email address of an administrator at your organisation. Your users will use this address if they have questions." +msgstr "" + +msgid "The following answer cannot be saved" +msgstr "" + +msgid "The items you select here will be displayed in the table below. You can sort the data by each of these headings or filter by entering a text string in the search box." +msgstr "Les éléments que vous sélectionnez ici s'afficherontt dans le tableaiu ci-après. Vous pouvez trier les données à partir de chacune de ces en-tête ou les filtrer en tapant une chaîne de caractères dans la zone de recherche." + +msgid "Themes" +msgstr "Thèmes" + +msgid "There are no public DMPs." +msgstr "Aucun DMP n'a été rendu public." + +msgid "There seems to be a problem with your logo. Please upload it again." +msgstr "" + +msgid "These are the basic details for your organisation." +msgstr "Voici/il sagit des informations de base sur votre organisme." + +msgid "This allows you to order questions within a section." +msgstr "Cette fonction vous permet de classer les questions dans une section." + +msgid "This allows you to order sections." +msgstr "Cette fonction vous permet de classer des sections." + +msgid "This allows you to order the phases of your template." +msgstr "Cette fonction vous permet de classer les phases de votre modèle." + +msgid "This document was generated by %{application_name}" +msgstr "%{application_name}" + +msgid "This must match what you entered in the previous field." +msgstr "" + +msgid "This page gives you an overview of your plan. It tells what your plan is based on and gives an overview of the questions that you will be asked." +msgstr "Cette page vous donne un aperçu de votre plan. Elle indique de quoi il s'inspire et donne une idée générale des questions auxquelles vous devrez répondre." + +#, fuzzy +msgid "This plan is based on the default template." +msgstr "templates" + +msgid "This plan is based on:" +msgstr "Ce plan sinspire de :" + +msgid "This section is locked for editing by " +msgstr "La modification de cette section a été verrouillée par " + +msgid "Title" +msgstr "Titre" + +msgid "Top" +msgstr "Haut" + +msgid "Top banner text" +msgstr "Texte de la bannière en haut décran" + +msgid "Transfer customisation" +msgstr "" + +#, fuzzy +msgid "Un-published" +msgstr "Publiée" + +msgid "Unable to link your account to %{scheme}." +msgstr "" + +msgid "Unable to unlink your account from %{is}." +msgstr "" + +msgid "Unknown column name." +msgstr "Nom de colonne inconnu." + +msgid "Unknown formatting setting" +msgstr "Réglage de mise en forme" + +msgid "Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'" +msgstr "Marge inconnue. Seules marges possibles : Haut, Bas, Gauche et Droite" + +msgid "Unlink account" +msgstr "Délier le compte" + +msgid "Unlink institutional credentials alert" +msgstr "Alerte de détachement dauthentifiant détablissement" + +msgid "Unlock my account" +msgstr "" + +msgid "Unpublish" +msgstr "" + +#, fuzzy +msgid "Unpublished" +msgstr "Publiée" + +msgid "Unpublished changes" +msgstr "" + +msgid "Unsaved answers" +msgstr "réponses non sauvegardées" + +msgid "Unsaved changes" +msgstr "Modification non enregistrée" + +msgid "Upload a new logo file" +msgstr "" + +msgid "Users" +msgstr "Utilisateurs" + +msgid "Using the generic Data Management Plan" +msgstr "" + +msgid "Version" +msgstr "Version" + +msgid "View" +msgstr "Visualiser" + +msgid "View all guidance" +msgstr "Voir tous les conseils" + +msgid "View all templates" +msgstr "Voir tous les modèles" + +msgid "View phase" +msgstr "Voir la phase" + +msgid "View plans" +msgstr "Voir les plans" + +msgid "Visibility" +msgstr "Visibilité" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the funder." +msgstr "templates" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to the research organisation." +msgstr "Organisation" + +#, fuzzy +msgid "We found multiple DMP templates corresponding to your funder." +msgstr "templates" + +msgid "Website" +msgstr "Site web" + +#, fuzzy +msgid "Welcome to " +msgstr "Bienvenue !" + +msgid "Welcome to %{application_name}" +msgstr "" + +msgid "Welcome." +msgstr "Bienvenue !" + +#, fuzzy +msgid "What research project are you planning?" +msgstr "plans" + +msgid "When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions." +msgstr "Quand vous créez une nouvelle phase dans votre modèle, une version sera créée automatiquement. Quand vous remplirez la grille ci-dessous, le système affichera des options pour créer des sections et des questions." + +#, fuzzy +msgid "Which DMP template would you like to use?" +msgstr "templates" + +msgid "Would you like to save them now?" +msgstr "Voulez-vous faire la sauvegarde maintenant?" + +msgid "Yes" +msgstr "" + +msgid "You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?" +msgstr "You are about to delete %{guidance_group_name}. This will affect guidance. Are you sure?" + +msgid "You are about to delete '%{guidance_summary}'. Are you sure?" +msgstr "Vous allez effacer %{guidance_summary}. En êtes-vous sûr?" + +msgid "You are about to delete '%{phase_title}'. This will affect versions, sections and questions linked to this phase. Are you sure?" +msgstr "Vous allez supprimer %{phase_title}. Cette opération affectera les versions, sections et questions liées à cette phase. En êtes-vous sûr?" + +msgid "You are about to delete '%{question_text}'. Are you sure?" +msgstr "Vous allez supprimer la question : %{question_text}. En êtes-vous sûr?" + +msgid "You are about to delete '%{section_title}'. This will affect questions linked to this section. Are you sure?" +msgstr "Vous allez supprimer %{section_title}. Cette opération affectera les questions liées à cette phase. En êtes-vous sûr?" + +#, fuzzy +msgid "You are about to delete a guidance for '%{question_text}'. Are you sure?" +msgstr "Vous allez supprimer la suggestion/lexemple de réponse à la questioo : %{question_text}. En êtes-vous sûr ?" + +msgid "You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?" +msgstr "Vous allez supprimer la suggestion/lexemple de réponse à la questioo : %{question_text}. En êtes-vous sûr ?" + +#, fuzzy +msgid "You are about to delete an example answer for '%{question_text}'. Are you sure?" +msgstr "Vous allez supprimer la suggestion/lexemple de réponse à la questioo : %{question_text}. En êtes-vous sûr ?" + +msgid "You are not authorized to perform this action." +msgstr "" + +#, fuzzy +msgid "You are viewing a historical version of this template. You will not be able to make changes." +msgstr "templates" + +#, fuzzy +msgid "You can add an example answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Vous pouvez ajouter un exemple ou une suggestion de réponse pour aider les utilisateurs. Ils safficheront au-dessus de la grille de réponse et on peut les copier/coller." + +msgid "You can add an example or suggested answer to help users respond. These will be presented above the answer box and can be copied/ pasted." +msgstr "Vous pouvez ajouter un exemple ou une suggestion de réponse pour aider les utilisateurs. Ils safficheront au-dessus de la grille de réponse et on peut les copier/coller." + +msgid "You can choose from:
    • - text area (large box for paragraphs);
    • - text field (for a short answer);
    • - checkboxes where options are presented in a list and multiple values can be selected;
    • - radio buttons where options are presented in a list but only one can be selected;
    • - dropdown like this box - only one option can be selected;
    • - multiple select box allows users to select several options from a scrollable list, using the CTRL key;
    " +msgstr "Vos choix possibles :
    • - une zone de texte (un grand cadre pour les paragraphes);
    • - un champ de texte (pour une réponse courte);
    • - les cases à cocher se présentent en une liste où plusieurs choix peuvent être sélectionnés;
    • - les boutons radio buttons se présentent en une liste où un seul choix est possible;
    • - la liste déroulante comme cet encadré, où une seule sélection est possible;
    • - un cadre à choix multiples permet à lutilisateur de faire plusieurs sélections dans une liste, avec la touche CTRL;
    " + +msgid "You can edit any of the details below." +msgstr "Vous pouvez modifiez les informations ci-dessous." + +msgid "You can not continue until you have filled in all of the required information." +msgstr "" + +#, fuzzy +msgid "You can not edit a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You can not publish a historical version of this template." +msgstr "templates" + +#, fuzzy +msgid "You cannot delete historical versions of this template." +msgstr "templates" + +msgid "You have altered answers but have not saved them:" +msgstr "Vous avez changé des réponses sans les sauvegarder:" + +msgid "You have been given " +msgstr "" + +#, fuzzy +msgid "You have been granted permission by your organisation to use our API. Your API token and instructions for using the API endpoints can be found " +msgstr "Organisation" + +msgid "You have un-published changes" +msgstr "" + +msgid "You have unsaved answers in the following sections:" +msgstr "" + +msgid "You must accept the terms and conditions to register." +msgstr "" + +msgid "You must enter a valid email address." +msgstr "Vous devez entrer un courriel valide." + +msgid "You need to sign in or sign up before continuing." +msgstr "" + +msgid "You now have " +msgstr "" + +msgid "Your" +msgstr "" + +msgid "Your ORCID" +msgstr "Votre ORCID" + +msgid "Your access to " +msgstr "" + +msgid "Your account has been successfully linked to %{scheme}." +msgstr "" + +msgid "Your account won't be created until you access the link above and set your password." +msgstr "" + +msgid "Your browser does not support the video tag." +msgstr "La balise
    '); + thead.append(''); tbody.append('') for (var i = 0, len = cols.length; i < len; i++) { - var title = cols[i].replace(/^\w|_/g, function(c) { return c === '_' ? ' ' : c.toUpperCase(); }), // FIXME: add titles to response for I18n? - label = $('').appendTo(thead), + var title = cols[i].replace(/^\w|_/g, function(c) { return c === '_' ? ' ' : c.toUpperCase(); }), + label = $('').appendTo(thead), container = $('').appendTo(tbody), input = $('').appendTo(container); @@ -55,11 +55,11 @@ input.attr('checked', 'checked'); } - thead.append(''); + thead.append(''); tbody.append('') - var submit = $('').appendTo(tfoot); - cancel = $('').appendTo(tfoot); + var submit = $('').appendTo(tfoot); + cancel = $('').appendTo(tfoot); cancel.click(function(e) { e.preventDefault(); @@ -72,7 +72,7 @@ /* 'My plans' filtering */ - var no_matches_message = $('').appendTo($('#dmp_table tbody')), + var no_matches_message = $('').appendTo($('#dmp_table tbody')), rows = $('#dmp_table tbody tr'), filter = $('#filter'); diff --git a/lib/assets/stylesheets/active_admin.scss b/lib/assets/stylesheets/active_admin.scss deleted file mode 100644 index b9759c9..0000000 --- a/lib/assets/stylesheets/active_admin.scss +++ /dev/null @@ -1,17 +0,0 @@ -// SASS variable overrides must be declared before loading up Active Admin's styles. -// -// To view the variables that Active Admin provides, take a look at -// `app/assets/stylesheets/active_admin/mixins/_variables.scss` in the -// Active Admin source. -// -// For example, to change the sidebar width: -// $sidebar-width: 242px; - -// Active Admin's got SASS! -@import "active_admin/mixins"; -@import "active_admin/base"; - -// Overriding any non-variable SASS must be done after the fact. -// For example, to change the default status-tag color: -// -// .status_tag { background: #6090DB; } diff --git a/lib/assets/stylesheets/admin.css.less b/lib/assets/stylesheets/admin.css.less index 132e00e..30da02c 100644 --- a/lib/assets/stylesheets/admin.css.less +++ b/lib/assets/stylesheets/admin.css.less @@ -567,7 +567,6 @@ } - /*********************************** Home page ************************************/ @@ -1186,6 +1185,10 @@ width: 250px; } +table.dmp_details_table tr td.tinymce{ + min-width: 400px; +} + table.dmp_details_table .text_area{ width: 90%; } @@ -1667,7 +1670,7 @@ padding-right: 20px; } table.tablesorter thead tr .header { - background-image: url(bg.gif); + background-image: asset-url("bg.gif"); background-repeat: no-repeat; background-position: center right; background-color: @orange_lighter_colour; @@ -1676,10 +1679,10 @@ table.tablesorter thead tr .headerSortUp { - background-image: url(asc.gif); + background-image: asset-url("asc.gif"); } table.tablesorter thead tr .headerSortDown { - background-image: url(desc.gif); + background-image: asset-url("desc.gif"); } diff --git a/lib/assets/stylesheets/application.css b/lib/assets/stylesheets/application.css index f4a3bdf..becfdeb 100644 --- a/lib/assets/stylesheets/application.css +++ b/lib/assets/stylesheets/application.css @@ -12,6 +12,7 @@ *= require_self *= require bootstrap_and_overrides *= require bootstrap.css - *= require bootstrap_and_overrides.css.less *= require select2.css - */ + *= require bootstrap_and_overrides.css.less + *= require roadmap-form.scss + */ \ No newline at end of file diff --git a/lib/assets/stylesheets/bootstrap_and_overrides.css.less b/lib/assets/stylesheets/bootstrap_and_overrides.css.less index f0b730b..11fcd58 100644 --- a/lib/assets/stylesheets/bootstrap_and_overrides.css.less +++ b/lib/assets/stylesheets/bootstrap_and_overrides.css.less @@ -471,6 +471,12 @@ border-top-color: @orange_lighter_colour; } +div.answer_notice { + background-color: #fee; + margin-bottom: 4px; + padding: 5px; +} + /*************************/ .formtastic{ @@ -499,6 +505,12 @@ } +/**** Substance Editor ***/ +.sc-rich-text-area { + border: 1px solid #ddd; + padding: 20px 10px; + padding-bottom: 0px; +} @@ -576,7 +588,21 @@ -moz-border-radius: 3px; } - +/*********************************** + User Profile Page +************************************/ +td.force-left .select2-container { + position: relative; + float: left; + clear: left; +} +.user-identifier { + background-repeat: no-repeat; + background-size: 25px; + background-position: 6px 50%; + margin-left: -7px; + padding: 3px 0 3px 35px; +} /*********************************** Home page @@ -730,6 +756,15 @@ margin-top:4px; } +.radio-label { + margin-left: 10px; +} + +#choose-template label { + display: inline +} + + .sign_up_org_label{ margin: 0 0 6px 0; float:left; @@ -961,6 +996,10 @@ text-shadow: none; } +.answer-notice { + width: 90%; +} + ol .choices-group{ padding-left: 20px; } @@ -1189,6 +1228,49 @@ clear:both; } +#plan-guidance-accordion { + & > .accordion-group { + background-color:@white_colour; + border-color: @white_colour; + border:none !important; + box-shadow:none !important; + -moz-box-shadow: none !important; + -webkit-box-shadow:none !important; + + & > .accordion-heading { + background-color:@white_colour; + border-bottom: 1px solid @orange_colour; + min-height: 50px; + + a { + padding-left:0px; + padding-right:0px; + } + + h3 { + float: left; + margin-top: 0px; + min-width:100%; + } + + span { + margin: 7px; + } + } + } + + .accordion-project { + clear: both; + } + + .accordion-inner { + border:none !important; + padding-right: 0px; + padding-left:0px; + } + +} + #project-accordion { & > .accordion-group { background-color:@white_colour; @@ -1770,15 +1852,15 @@ table.tablesorter thead { th.header { cursor: pointer; - background: url('/assets/bg.gif') no-repeat center right; + background: asset-url('bg.gif') no-repeat center right; } th.headerSortDown { - background: @orange_lighter_colour url('/assets/desc.gif') no-repeat center right; + background: @orange_lighter_colour asset-url('desc.gif') no-repeat center right; } th.headerSortUp { - background: @orange_lighter_colour url('/assets/asc.gif') no-repeat center right; + background: @orange_lighter_colour asset-url('asc.gif') no-repeat center right; } } diff --git a/lib/assets/stylesheets/roadmap-form.scss b/lib/assets/stylesheets/roadmap-form.scss new file mode 100644 index 0000000..5a860ae --- /dev/null +++ b/lib/assets/stylesheets/roadmap-form.scss @@ -0,0 +1,259 @@ +@import "font-awesome"; + +$font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +$header-font: "GillSansLight"; + +$white: #FFF; +$dark-grey: #333; + +$primary-color: #F49700; +$primary-admin-color: #0057A7; +$disabled-button-color: #CCC; +$cancel-button-color: #827D7E; +$reverse-text: #FFF; + +/* See `.combobox-clear-button` for an example of this mixin in use */ +@mixin icon($icon) { + @extend .fa; + @extend .fa-#{$icon}:before; +} + +.arrow-left { + display: inline-block; + width: 0; + height: 0; + border-top: 12px solid transparent; + border-bottom: 12px solid transparent; + border-right: 12px solid $dark-grey; +} + +.main_header { + margin-bottom: 20px; +} + +.content-box { + +} + +/* Roadmap Form Styling */ +/* ------------------------------------------------ */ +form.roadmap-form { + + fieldset.padded { + padding: 10px 10px 25px 10px; + } + + /* Fieldset with labels over inputs */ + fieldset.standard { + padding: 5px; + background-color: $white; + + margin-bottom: 25px; + + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + + label, + input[type="checkbox"], + .combobox-container, + .left-indent { + margin-left: 15px; + } + + input[type="text"], select { + margin-bottom: 15px; + } + + input[type="checkbox"] { + vertical-align: top; + } + + .checkbox-label { + display: inline-block; + margin-left: 5px; + } + } + + /* Fieldset with labels to the left of inputs */ + fieldset.side-by-side { + .mce-tinymce { + display: inline-block; + } + + div { + label, + input[type="checkbox"], + .combobox-container, + .identifier-scheme { + display: inline-block; + } + + .identifier-scheme-indent { + margin-left: -5px; + } + + label { + width: 25%; + text-align: right; + margin-right: 10px; + vertical-align: middle; + } + + input.form-submit, + button.form-cancel { + font-size: 10pt; + } + } + + .button-spacer { + display: inline-block; + width: 21%; + } + } + + /* Generic Fieldset Settings */ + fieldset legend { + font-family: $header-font; + color: $primary-color; + font-size: 26px; + font-weight: normal; + text-decoration: none; + + float: left; /* positions the legend within the fieldset box */ + border-bottom: none; + } + + div.inline { + display: inline-block; + } + .left-indent { + margin-left: 15px; + } + .input-extra-large { + width: 70%; + } + .input-large { + width: 50%; + } + .input-medium { + width: 30%; + } + .input-small { + width: 10%; + } + /* Used for the jquery autocomplete combobox on side-by-side fieldsets */ + .fixed-width-large { + width: 550px; + } + + /* Accessible Form Buttons */ + input.form-submit { + background-color: $primary-color; + color: $reverse-text; + font-size: 14px; + padding: 4px 12px; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + /* Override the button color for the Org Admin sections */ + input[type="submit"].admin{ + background-color: $primary-admin-color; + } + input.form-submit[aria-disabled='true'] { + background-color: $disabled-button-color; + } + input.form-submit:focus + [role="tooltip"] { + display: inline-block; + } + button.form-cancel { + background-color: $cancel-button-color; + color: $reverse-text; + font-size: 14px; + padding: 4px 12px; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + .submit-tooltip { + display: none; + margin-left: 5px; + + .arrow-left { + vertical-align: middle; + margin-right: -5px; + } + .submit-tooltip-msg { + color: $white; + background-color: $dark-grey; + padding: 5px 5px 8px 5px; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + } +} + +/* Accessible JQuery combobox */ +/* ------------------------------------------------------ */ +.invisible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.combobox-container { + position: relative; + max-width: 585px; + + font-family: $font-family; +} + +.combobox-suggestions { + position: absolute; + left: 0; + width: 562px; + margin-top: -10px; + background: #fff; + z-index: 99; +} +.combobox-suggestion { + color: #666; + border-bottom: 1px solid #000; + border-left: 1px solid #000; + border-right: 1px solid #000; + padding: 5px 10px 5px 10px; + cursor: pointer; + text-align: left; +} +.combobox-suggestion:first-child { + border-top: 1px solid #000; +} +.combobox-suggestion:hover, +.combobox-suggestion:focus { + color: $white; + background-color: $primary-color; +} + +.combobox-clear-button { + @include icon(times-circle); + display: inline; + position: absolute; + border: none; + background: transparent; + padding-top: 3px; + font-size: 16pt; +} + +/* http://geektnt.com/how-to-remove-x-from-search-input-field-on-chrome-and-ie.html */ +.js-combobox[type=text]::-ms-clear { display: none; width: 0; height: 0; } +.js-combobox[type=text]::-ms-reveal { display: none; width: 0; height: 0; } \ No newline at end of file diff --git a/lib/global_helpers.rb b/lib/global_helpers.rb index ae096ae..b630113 100644 --- a/lib/global_helpers.rb +++ b/lib/global_helpers.rb @@ -2,7 +2,7 @@ ## # takes in a string which is meant to be constant, and looks it up in the default - # (en-UK) locale. This should ensure that the back-end remains constant and consistantly called + # (en_GB) locale. This should ensure that the back-end remains constant and consistantly called # # @param [String] str the string which will be looked up in the localisation # @return [String] the constant which the string defines diff --git a/lib/tasks/migrate.rake b/lib/tasks/migrate.rake index 87bbe10..f436586 100644 --- a/lib/tasks/migrate.rake +++ b/lib/tasks/migrate.rake @@ -15,6 +15,13 @@ Rake::Task['migrate:permissions'].execute end + desc "perform all post-migration tasks" + task cleanup: :environment do + Rake::Task['migrate:fix_languages'].execute + Rake::Task['migrate:single_published_template'].execute + end + + desc "seed database with default values for new data structures" task seed: :environment do # seed roles to database @@ -78,23 +85,35 @@ # seed languages to database languages = { - 'English(UK)' => { - abbreviation: 'en-UK', - description: 'UK English language used as default', - name: 'English(UK)', - default_language: true + 'English(GB)' => { + abbreviation: 'en_GB', + description: '', + name: 'English (GB)', + default_language: true + }, + 'English(US)' => { + abbreviation: 'en_US', + description: '', + name: 'English (US)', + default_language: false }, 'FR' => { - abbreviation: 'fr', - description: '', - name: 'fr', - default_language: false + abbreviation: 'fr', + description: '', + name: 'Français', + default_language: false }, 'DE' => { abbreviation: 'de', description: '', - name: 'de', + name: 'Deutsch', default_language: false + }, + 'Español' => { + abbreviation: 'es', + description: '', + name: 'Español', + default_language: false } } @@ -139,4 +158,100 @@ end end + + desc "replaces languages in incorrect formats and seeds all correct formats" + task fix_languages: :environment do + languages = [ + { abbreviation: 'en_GB', + old_abbreviation: 'en-UK', + description: '', + name: 'English (GB)', + default_language: true}, + { abbreviation: 'en_US', + old_abbreviation: 'en-US', + description: '', + name: 'English (US)', + default_language: false}, + { abbreviation: 'fr', + old_abbreviation: 'fr', + description: '', + name: 'Français', + default_language: false}, + { abbreviation: 'de', + old_abbreviation: 'de', + description: '', + name: 'Deutsch', + default_language: false}, + { abbreviation: 'es', + old_abbreviation: 'es', + description: '', + name: 'Español', + default_language: false} + ] + + languages.each do |lang_data| + # if the old abbreviation exists, remove and replace the data + lang = Language.find_by(abbreviation: lang_data[:old_abbreviation]) + if lang.present? + lang.abbreviation = lang_data[:abbreviation] + lang.description = lang_data[:description] + lang.name = lang_data[:name] + lang.default_language = lang_data[:default_language] + lang.save! + else + # if nothing batching either abbreviation exists, replace with new abbreviation + lang = Language.find_by(abbreviation: lang_data[:abbreviation]) + if lang.blank? + lang = Language.new + lang.abbreviation = lang_data[:abbreviation] + lang.description = lang_data[:description] + lang.name = lang_data[:name] + lang.default_language = lang_data[:default_language] + lang.save! + end + end + end + + end + + desc "move old ORCID from user table to user_identifiers" + task move_orcids: :environment do + if IdentifierScheme.find_by(name: 'orcid').nil? + IdentifierScheme.create!(name: 'orcid', description: 'ORCID', active: true) + end + + scheme = IdentifierScheme.find_by(name: 'orcid') + + unless scheme.nil? + User.all.each do |u| + if u.respond_to?(:orcid_id) + if u.orcid_id.present? + if u.orcid_id.gsub('orcid.org/', '').match(/^[\d-]+/) + u.user_identifiers << UserIdentifier.new(identifier_scheme: scheme, + identifier: u.orcid_id.gsub('orcid.org/', '')) + u.save! + end + end + end + end + end + end + + desc "enforce single published version for templates" + task single_published_template: :environment do + # for each group of versions of a template + Template.all.pluck(:dmptemplate_id).uniq.each do |dmptemplate_id| + published = false + Template.where(dmptemplate_id: dmptemplate_id).order(version: :desc).each do |template| + # leave the first published template we find alone + if !published && template.published + published = true + elsif published && template.published + template.published = false + template.save! + end + end + end + end + end diff --git a/lib/tasks/templates.rake b/lib/tasks/templates.rake new file mode 100644 index 0000000..6bc07bf --- /dev/null +++ b/lib/tasks/templates.rake @@ -0,0 +1,88 @@ +namespace :templates do + + desc "Initializes the dirty flag on templates" + task set_dirty_flags: :environment do + Org.all.each do |org| + Template.dmptemplate_ids(org).each do |id| + current = Template.current(org, id) + live = Template.live(org, id) + + # If its been published or the current date is greater than the live date then it has outstanding changes + if !live.nil? + if live.updated_at.strftime("%Y-%m-%d %H:%M") < + current.updated_at.strftime("%Y-%m-%d %H:%M") + + current.dirty = true + current.save! + end + end + end + end + end + + desc "Cleanup published flags" + task clean_up_published_flags: :environment do + Org.all.each do |org| + Template.dmptemplate_ids(org).each do |id| + live = Template.live(org, id) + + # If its been published or the current date is greater than the live date then it has outstanding changes + if !live.nil? + Template.where("updated_at < ? AND published = ?", + live.updated_at, true).each do |template| + template.published = false + template.save! + end + end + end + end + end + + desc "Cleanup excess versions" + task clean_up_excess_versions: :environment do + Org.all.each do |org| + Template.dmptemplate_ids(org).each do |id| + versions = Template.where(org: org, dmptemplate_id: id).pluck(:version).uniq + + # Only keep the latest record for each version + versions.each do |ver| + templates = Template.where(org: org, dmptemplate_id: id, version: ver).order(published: :desc, updated_at: :desc) + + # If there is more than one record with the same version then delete it + if templates.count > 1 + templates[1..templates.count].each do |t| + if t.plans.count <= 0 + + # Cycle through all of this template's dependencies first + t.phases.each do |p| + p.sections.each do |s| + s.questions.each do |q| + q.suggested_answers do |sa| + sa.destroy + end + + q.question_options do |qo| + qo.destroy + end + + q.destroy + end + + s.destroy + end + + p.destroy + end + + t.destroy + + else + puts "UNABLE to delete #{t.id} because it has a plan" + end + end + end + end + end + end + end +end \ No newline at end of file diff --git a/public/html/Ability.html b/public/html/Ability.html new file mode 100644 index 0000000..d808822 --- /dev/null +++ b/public/html/Ability.html @@ -0,0 +1,388 @@ + + + + + + +class Ability - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Ability

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/ability.rb, line 4
    +def initialize(user)
    +  # Define abilities for the passed in user here. For example:
    +
    +  #
    +
    +    user ||= User.new # guest user (not logged in)
    +
    +    if user.has_role? :admin
    +      can :manage, :all
    +    else
    +      can :read, :all
    +    end
    +
    +  can :manage_settings, User do |viewed_user|
    +    viewed_user.present? && user.id == viewed_user.id
    +  end
    +  #
    +
    +  # The first argument to `can` is the action you are giving the user 
    +
    +  # permission to do.
    +
    +  # If you pass :manage it will apply to every action. Other common actions
    +
    +  # here are :read, :create, :update and :destroy.
    +
    +  #
    +
    +  # The second argument is the resource the user can perform the action on. 
    +
    +  # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    +
    +  # class of the resource.
    +
    +  #
    +
    +  # The third argument is an optional hash of conditions to further filter the
    +
    +  # objects.
    +
    +  # For example, here the user can only update published articles.
    +
    +  #
    +
    +  #   can :update, Article, :published => true
    +
    +  #
    +
    +  # See the wiki for details:
    +
    +  # https://github.com/ryanb/cancan/wiki/Defining-Abilities
    +
    + 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ActiveAdmin.html b/public/html/ActiveAdmin.html new file mode 100644 index 0000000..aeb8dc4 --- /dev/null +++ b/public/html/ActiveAdmin.html @@ -0,0 +1,272 @@ + + + + + + +module ActiveAdmin - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module ActiveAdmin

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/ActiveAdmin/Views.html b/public/html/ActiveAdmin/Views.html new file mode 100644 index 0000000..8b4e4fe --- /dev/null +++ b/public/html/ActiveAdmin/Views.html @@ -0,0 +1,272 @@ + + + + + + +module ActiveAdmin::Views - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module ActiveAdmin::Views

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/ActiveAdmin/Views/Pages.html b/public/html/ActiveAdmin/Views/Pages.html new file mode 100644 index 0000000..cc0eccd --- /dev/null +++ b/public/html/ActiveAdmin/Views/Pages.html @@ -0,0 +1,272 @@ + + + + + + +module ActiveAdmin::Views::Pages - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module ActiveAdmin::Views::Pages

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/ActiveAdmin/Views/Pages/Base.html b/public/html/ActiveAdmin/Views/Pages/Base.html new file mode 100644 index 0000000..0920d9a --- /dev/null +++ b/public/html/ActiveAdmin/Views/Pages/Base.html @@ -0,0 +1,331 @@ + + + + + + +class ActiveAdmin::Views::Pages::Base - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ActiveAdmin::Views::Pages::Base

    + +
    + +

    lib/active_admin_views_pages_base.rb

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Private Instance Methods

    + + + + + +
    + +
    + +
    + + + + diff --git a/public/html/AdminUser.html b/public/html/AdminUser.html new file mode 100644 index 0000000..25177a0 --- /dev/null +++ b/public/html/AdminUser.html @@ -0,0 +1,279 @@ + + + + + + +class AdminUser - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class AdminUser

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Answer.html b/public/html/Answer.html new file mode 100644 index 0000000..0693ae3 --- /dev/null +++ b/public/html/Answer.html @@ -0,0 +1,279 @@ + + + + + + +class Answer - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Answer

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/AnswersController.html b/public/html/AnswersController.html new file mode 100644 index 0000000..b017bbd --- /dev/null +++ b/public/html/AnswersController.html @@ -0,0 +1,360 @@ + + + + + + +class AnswersController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class AnswersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /answers POST /answers.json

    + + + +
    +
    # File app/controllers/answers_controller.rb, line 5
    +def create
    +        @answer = Answer.new(params[:answer])
    +        if (user_signed_in?) && @answer.plan.editable_by(current_user.id) then
    +                old_answer = @answer.plan.answer(@answer.question_id, false)
    +                proceed = false
    +                @answer.text = params["answer-text-#{@answer.question_id}".to_sym]
    +                if (old_answer.nil? && @answer.text != "") || ((!old_answer.nil?) && (old_answer.text != @answer.text)) then
    +                        proceed = true
    +                end
    +    
    +                if (@answer.question.question_format.title == I18n.t("helpers.checkbox") || 
    +        @answer.question.question_format.title == I18n.t("helpers.multi_select_box") ||
    +        @answer.question.question_format.title == I18n.t("helpers.radio_buttons") || 
    +        @answer.question.question_format.title == I18n.t("helpers.dropdown")) then
    +                        if (old_answer.nil? && @answer.option_ids.count > 0) || ((!old_answer.nil?) && (old_answer.option_ids - @answer.option_ids).count != 0 && (@answer.option_ids - old_answer.option_ids).count != 0) then
    +                                proceed = true
    +                        end
    +                end
    +                if proceed
    +                        respond_to do |format|
    +                                if @answer.save
    +                                        format.html { redirect_to :back, status: :found, notice: 'Answer was successfully recorded.' }
    +                                        format.json { render json: @answer, status: :created, location: @answer }
    +                                else
    +                                        format.html { redirect_to :back, notice: 'There was an error saving the answer.' }
    +                                        format.json { render json: @answer.errors, status: :unprocessable_entity }
    +                                end
    +                        end
    +                else
    +                        respond_to do |format|
    +                                format.html { redirect_to :back, notice: 'No change in answer content - not saved.' }
    +                                format.json { render json: @answer.errors, status: :unprocessable_entity }
    +                        end
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ApplicationController.html b/public/html/ApplicationController.html new file mode 100644 index 0000000..4e977fd --- /dev/null +++ b/public/html/ApplicationController.html @@ -0,0 +1,529 @@ + + + + + + +class ApplicationController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ApplicationController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_sign_in_error_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 32
    +def after_sign_in_error_path_for(resource)
    +  session[:previous_url] || root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_sign_in_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 24
    +def after_sign_in_path_for(resource)
    +  session[:previous_url] || root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_sign_up_error_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 36
    +def after_sign_up_error_path_for(resource)
    +  session[:previous_url] || root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_sign_up_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 28
    +def after_sign_up_path_for(resource)
    +  session[:previous_url] || root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authenticate_admin!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 40
    +def authenticate_admin!
    +        redirect_to root_path unless user_signed_in? && current_user.can_super_admin?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + get_plan_list_columns() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 44
    +def get_plan_list_columns
    +        if user_signed_in?
    +                @selected_columns = current_user.settings(:plan_list).columns
    +                @all_columns = Settings::PlanList::ALL_COLUMNS
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + store_location() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 13
    +def store_location
    + # store last url - this is needed for post-login redirect to whatever the user last visited.
    +
    +        if (request.fullpath != "/users/sign_in" && \
    +                request.fullpath != "/users/sign_up" && \
    +                request.fullpath != "/users/password" && \
    +    request.fullpath != "/users/sign_up?nosplash=true" && \
    +                !request.xhr?) # don't store ajax calls
    +
    +          session[:previous_url] = request.fullpath 
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ApplicationHelper.html b/public/html/ApplicationHelper.html new file mode 100644 index 0000000..c5ea91c --- /dev/null +++ b/public/html/ApplicationHelper.html @@ -0,0 +1,453 @@ + + + + + + +module ApplicationHelper - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module ApplicationHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + devise_mapping() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 10
    +def devise_mapping
    +        @devise_mapping ||= Devise.mappings[:user]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + javascript(*files) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 14
    +def javascript(*files)
    +  content_for(:head) { javascript_include_tag(*files) }
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + resource() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 6
    +def resource
    +        @resource ||= User.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + resource_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 2
    +def resource_name
    +        :user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Comment.html b/public/html/Comment.html new file mode 100644 index 0000000..9f7cf6b --- /dev/null +++ b/public/html/Comment.html @@ -0,0 +1,325 @@ + + + + + + +class Comment - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Comment

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/comment.rb, line 11
    +def to_s
    +    "#{text}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/CommentsController.html b/public/html/CommentsController.html new file mode 100644 index 0000000..7c5267e --- /dev/null +++ b/public/html/CommentsController.html @@ -0,0 +1,538 @@ + + + + + + +class CommentsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class CommentsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + archive() + click to toggle source +
    + + +
    + +

    ARCHIVE /comments/1 ARCHIVE /comments/1.json

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 73
    +def archive
    +  @comment = Comment.find(params[:comment][:id])
    +  @comment.archived = true
    +  @comment.archived_by = params[:comment][:archived_by]
    +  
    +  @plan = Plan.find(@comment.plan_id)
    +  @project = Project.find(@plan.project_id)
    +
    +  respond_to do |format|
    +    if @comment.update_attributes(params[:comment])
    +      session[:question_id_comments] = @comment.question_id
    +      format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: 'Comment has been removed.' }     
    +    end   
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /comments POST /comments.json

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 32
    +def create
    + if user_signed_in? then
    +      @comment = Comment.new(params[:new_comment])
    +      @comment.text = params["#{params[:new_comment][:question_id]}new_comment_text"]
    +      @comment.question_id = params[:new_comment][:question_id]
    +      @comment.user_id = params[:new_comment][:user_id]
    +      @comment.plan_id = params[:new_comment][:plan_id]
    +      
    +      @plan = Plan.find(@comment.plan_id)
    +      @project = Project.find(@plan.project_id)
    +      
    +      respond_to do |format|
    +        if @comment.save
    +          session[:question_id_comments] = @comment.question_id
    +          format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: 'Comment was successfully created.' }
    +          format.json { head :no_content  }
    +        end
    +      end
    +  end    
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /comments/1/edit

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 26
    +def edit
    +  @comment = Comment.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /comments GET /comments.json

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 4
    +def index
    +  @comments = Comment.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @comments }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /comments/1 GET /comments/1.json

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 15
    +def show
    +  @comment = Comment.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @comment }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /comments/1 PUT /comments/1.json

    + + + +
    +
    # File app/controllers/comments_controller.rb, line 55
    +def update
    +  @comment = Comment.find(params[:comment][:id])
    +  @comment.text = params["#{params[:comment][:id]}_comment_text"]
    +  
    +  @plan = Plan.find(@comment.plan_id)
    +  @project = Project.find(@plan.project_id)
    +  
    +  respond_to do |format|
    +    if @comment.update_attributes(params[:comment])
    +      session[:question_id_comments] = @comment.question_id
    +      format.html { redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: 'Comment was successfully updated.' }
    +      format.json { head :no_content }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ConfirmationsController.html b/public/html/ConfirmationsController.html new file mode 100644 index 0000000..11e2609 --- /dev/null +++ b/public/html/ConfirmationsController.html @@ -0,0 +1,325 @@ + + + + + + +class ConfirmationsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ConfirmationsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Protected Instance Methods

    + + +
    + +
    + after_confirmation_path_for(resource_name, resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/confirmations_controller.rb, line 5
    +def after_confirmation_path_for(resource_name, resource)
    +  root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ContactsController.html b/public/html/ContactsController.html new file mode 100644 index 0000000..5cbc8c6 --- /dev/null +++ b/public/html/ContactsController.html @@ -0,0 +1,350 @@ + + + + + + +class ContactsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ContactsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/contacts_controller.rb, line 2
    +def create
    +        @contact = ContactUs::Contact.new(params[:contact_us_contact])
    +        if (!user_signed_in?)
    +                if verify_recaptcha(:message => "You have not added the validation words correctly") && @contact.save
    +                        flash[:notice] = t('contact_us.notices.success')
    +                        if user_signed_in? then
    +                             redirect_to :controller => 'projects', :action => 'index'
    +                     else
    +                             redirect_to(root_path)
    +                     end
    +                else
    +                     flash[:alert]  = t('contact_us.notices.error')
    +                     render_new_page
    +                end
    +        else
    +                if @contact.save
    +                        flash[:notice] = t('contact_us.notices.success')
    +                        if user_signed_in? then
    +                             redirect_to :controller => 'projects', :action => 'index'
    +                     else
    +                             redirect_to(root_path)
    +                     end
    +                else
    +                     flash[:alert] = t('contact_us.notices.error')
    +                     render_new_page
    +                end
    +        end           
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/CustomFailure.html b/public/html/CustomFailure.html new file mode 100644 index 0000000..00e20d5 --- /dev/null +++ b/public/html/CustomFailure.html @@ -0,0 +1,361 @@ + + + + + + +class CustomFailure - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class CustomFailure

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + redirect_url() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/custom_failure.rb, line 2
    +def redirect_url
    +  root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + respond() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/custom_failure.rb, line 6
    +def respond
    +  if http_auth?
    +    http_auth
    +  else
    +    redirect
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/DMPonline4.html b/public/html/DMPonline4.html new file mode 100644 index 0000000..299d664 --- /dev/null +++ b/public/html/DMPonline4.html @@ -0,0 +1,274 @@ + + + + + + +module DMPonline4 - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module DMPonline4

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/DMPonline4/Application.html b/public/html/DMPonline4/Application.html new file mode 100644 index 0000000..35ca2cd --- /dev/null +++ b/public/html/DMPonline4/Application.html @@ -0,0 +1,280 @@ + + + + + + +class DMPonline4::Application - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class DMPonline4::Application

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Dmptemplate.html b/public/html/Dmptemplate.html new file mode 100644 index 0000000..3de2e67 --- /dev/null +++ b/public/html/Dmptemplate.html @@ -0,0 +1,602 @@ + + + + + + +class Dmptemplate - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Dmptemplate

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + funders_and_own_templates(org_id) + click to toggle source +
    + + +
    + +

    returns an array with all funders and own institutional templates

    + + + +
    +
    # File app/models/dmptemplate.rb, line 63
    +def self.funders_and_own_templates(org_id)
    +        funders_templates = self.funders_templates
    +
    +#verify if org type is not a funder
    +
    +current_org = Organisation.find(org_id)
    +if current_org.organisation_type.name != I18n.t("helpers.org_type.funder") then 
    +    own_institutional_templates = self.own_institutional_templates(org_id)
    +        else
    +    own_institutional_templates = []
    +end    
    +    
    +        templates_list = Array.new
    +        templates_list += own_institutional_templates
    +        templates_list += funders_templates
    +        templates_list = templates_list.sort_by { |f| f['title'].downcase }
    +                        
    +        return templates_list
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funders_templates() + click to toggle source +
    + + +
    + +

    returns all funders templates

    + + + +
    +
    # File app/models/dmptemplate.rb, line 44
    +    def self.funders_templates
    +            new_org_obejcts = OrganisationType.find_by_name(I18n.t("helpers.org_type.funder")).organisations
    +      org_templates = Array.new
    +    
    +    new_org_obejcts.each do |neworg|
    +    org_templates += neworg.dmptemplates
    +end
    +
    +return org_templates        
    +    end
    +
    + +
    + + + + +
    + + +
    + +
    + own_institutional_templates(org_id) + click to toggle source +
    + + +
    + +

    returns all institutional templates bellowing to the current user's org

    + + + +
    +
    # File app/models/dmptemplate.rb, line 57
    +def self.own_institutional_templates(org_id)
    +        new_templates = self.where("organisation_id = ?", org_id)
    +        return new_templates
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + templates_org_type(ot) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/dmptemplate.rb, line 32
    +def self.templates_org_type(ot)
    +  new_org_obejcts = OrganisationType.find_by_name(ot).organisations
    +  
    +  org_templates = Array.new
    +  new_org_obejcts.each do |neworg|
    +     org_templates += neworg.dmptemplates.where("published = ?", true)
    +  end
    +  
    +  return org_templates
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + has_customisations?(org_id, temp) + click to toggle source +
    + + +
    + +

    verify if a template has customisation by current user's org

    + + + +
    +
    # File app/models/dmptemplate.rb, line 88
    +def has_customisations?(org_id, temp)
    +        if temp.organisation_id != org_id then
    +                temp.phases.each do |phase|
    +                        phase.versions.each do |version|
    +                                version.sections.each do |section|
    +                                        return true if section.organisation_id == org_id 
    +                                                                                
    +                                end        
    +                        end
    +                        return false 
    +                end
    +        else
    +                return false         
    +        end   
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + has_published_versions?() + click to toggle source +
    + + +
    + +

    verify if there are any publish version for the template

    + + + +
    +
    # File app/models/dmptemplate.rb, line 106
    +def has_published_versions?
    +        phases.each do |phase|
    +                return true if !phase.latest_published_version.nil?
    +        end
    +        return false 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + org_type() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/dmptemplate.rb, line 82
    +def org_type
    +        org_type = organisation.organisation_type.name
    +        return org_type
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/dmptemplate.rb, line 28
    +def to_s
    +  "#{title}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/DmptemplatesController.html b/public/html/DmptemplatesController.html new file mode 100644 index 0000000..f4c7d37 --- /dev/null +++ b/public/html/DmptemplatesController.html @@ -0,0 +1,1427 @@ + + + + + + +class DmptemplatesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class DmptemplatesController

    + +
    +
    Project: +
    +

    DMPonline v4

    +
    Description: +
    +

    This controller is responsible for all the actions in the admin interface +under templates (e.g. phases, versions, sections, questions, suggested +answer) (index; show; create; edit; delete)

    +
    Copyright: +
    +

    Digital Curation Centre

    +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_addphase() + click to toggle source +
    + + +
    + +

    add a new phase to a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 187
    +def admin_addphase
    +        if user_signed_in? && current_user.can_org_admin? then
    +                @dmptemplate = Dmptemplate.find(params[:id])
    +                @phase = Phase.new
    +                if @dmptemplate.phases.count == 0 then
    +                        @phase.number = '1'
    +                else
    +                        @phase.number = @dmptemplate.phases.count + 1
    +                end
    +
    +                respond_to do |format|
    +      format.html
    +    end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_cloneversion() + click to toggle source +
    + + +
    + +

    clone a version of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 293
    +def admin_cloneversion
    +        if user_signed_in? && current_user.can_org_admin? then
    +@old_version = Version.find(params[:version_id])
    +                @version = @old_version.amoeba_dup
    +                @phase = @version.phase
    +
    +    respond_to do |format|
    +      if @version.save
    +        format.html { redirect_to admin_phase_dmptemplate_path(@phase, :version_id => @version.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') }
    +        format.json { head :no_content }
    +      else
    +        format.html { render action: "admin_phase" }
    +        format.json { render json: @version.errors, status: :unprocessable_entity }
    +      end
    +    end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_create() + click to toggle source +
    + + +
    + +

    POST /dmptemplates POST /dmptemplates.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 81
    +def admin_create
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @dmptemplate = Dmptemplate.new(params[:dmptemplate])
    +          @dmptemplate.organisation_id = current_user.organisation.id
    +          @dmptemplate.description = params['template-desc']
    +
    +          respond_to do |format|
    +            if @dmptemplate.save
    +              format.html { redirect_to admin_template_dmptemplate_path(@dmptemplate), notice: I18n.t('org_admin.templates.created_message') }
    +              format.json { render json: @dmptemplate, status: :created, location: @dmptemplate }
    +            else
    +              format.html { render action: "admin_new" }
    +              format.json { render json: @dmptemplate.errors, status: :unprocessable_entity }
    +            end
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_createphase() + click to toggle source +
    + + +
    + +

    create a phase

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 204
    +      def admin_createphase
    +  if user_signed_in? && current_user.can_org_admin? then
    +             @phase = Phase.new(params[:phase])
    +          @phase.description = params["phase-desc"]
    +          @version = @phase.versions.build
    +          @version.title = "#{@phase.title} v.1"
    +          @version.phase_id = @phase.id
    +          @version.number = 1
    +          @version.published = false
    +
    +          respond_to do |format|
    +            if @phase.save
    +              format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "admin_phase" }
    +              format.json { render json: @phase.errors, status: :unprocessable_entity }
    +            end
    +                      end
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_createquestion() + click to toggle source +
    + + +
    + +

    create a question

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 386
    +      def admin_createquestion
    +  if user_signed_in? && current_user.can_org_admin? then
    +             @question = Question.new(params[:question])
    +          @question.guidance = params["new-question-guidance"]
    +          @question.default_value = params["new-question-default-value"]
    +
    +
    +          respond_to do |format|
    +            if @question.save
    +              format.html { redirect_to admin_phase_dmptemplate_path(:id => @question.section.version.phase_id, :version_id => @question.section.version_id, :section_id => @question.section_id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "admin_phase" }
    +              format.json { render json: @question.errors, status: :unprocessable_entity }
    +            end
    +                      end
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_createsection() + click to toggle source +
    + + +
    + +

    create a section

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 328
    +      def admin_createsection
    +  if user_signed_in? && current_user.can_org_admin? then
    +             @section = Section.new(params[:section])
    +          @section.description = params["section-desc"]
    +
    +          respond_to do |format|
    +            if @section.save
    +              format.html { redirect_to admin_phase_dmptemplate_path(:id => @section.version.phase_id, :version_id => @section.version_id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "admin_phase" }
    +              format.json { render json: @section.errors, status: :unprocessable_entity }
    +            end
    +                      end
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_createsuggestedanswer() + click to toggle source +
    + + +
    + +

    SUGGESTED ANSWERS create suggested answers

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 446
    +   def admin_createsuggestedanswer
    +   if user_signed_in? && current_user.can_org_admin? then
    +           @suggested_answer = SuggestedAnswer.new(params[:suggested_answer])
    +
    +       respond_to do |format|
    +         if @suggested_answer.save
    +           format.html { redirect_to admin_phase_dmptemplate_path(:id => @suggested_answer.question.section.version.phase_id, :version_id => @suggested_answer.question.section.version_id, :section_id => @suggested_answer.question.section_id, :question_id => @suggested_answer.question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') }
    +           format.json { head :no_content }
    +         else
    +           format.html { render action: "admin_phase" }
    +           format.json { render json: @suggested_answer.errors, status: :unprocessable_entity }
    +         end
    +           end
    +    end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroy() + click to toggle source +
    + + +
    + +

    DELETE /dmptemplates/1 DELETE /dmptemplates/1.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 105
    +def admin_destroy
    +      if user_signed_in? && current_user.can_org_admin? then
    +             @dmptemplate = Dmptemplate.find(params[:id])
    +          @dmptemplate.destroy
    +
    +          respond_to do |format|
    +            format.html { redirect_to admin_index_dmptemplate_path }
    +            format.json { head :no_content }
    +          end
    +             else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +      end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroyphase() + click to toggle source +
    + + +
    + +

    delete a version, sections and questions

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 246
    +def admin_destroyphase
    +if user_signed_in? && current_user.can_org_admin? then
    +       @phase = Phase.find(params[:phase_id])
    +       @dmptemplate = @phase.dmptemplate
    +    @phase.destroy
    +
    +    respond_to do |format|
    +      format.html { redirect_to admin_template_dmptemplate_path(@dmptemplate), notice: I18n.t('org_admin.templates.destroyed_message') }
    +      format.json { head :no_content }
    +    end
    +       end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroyquestion() + click to toggle source +
    + + +
    + +

    delete a version, sections and questions

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 428
    +def admin_destroyquestion
    +if user_signed_in? && current_user.can_org_admin? then
    +       @question = Question.find(params[:question_id])
    +       @section = @question.section
    +                @version = @section.version
    +       @phase = @version.phase
    +    @question.destroy
    +
    +    respond_to do |format|
    +      format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.destroyed_message') }
    +      format.json { head :no_content }
    +    end
    +       end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroysection() + click to toggle source +
    + + +
    + +

    delete a section and questions

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 368
    +def admin_destroysection
    +if user_signed_in? && current_user.can_org_admin? then
    +       @section = Section.find(params[:section_id])
    +       @version = @section.version
    +       @phase = @version.phase
    +    @section.destroy
    +
    +    respond_to do |format|
    +      format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id,  :edit => 'true' ), notice: I18n.t('org_admin.templates.destroyed_message') }
    +      format.json { head :no_content }
    +    end
    +       end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroysuggestedanswer() + click to toggle source +
    + + +
    + +

    delete a suggested answer

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 484
    +def admin_destroysuggestedanswer
    +if user_signed_in? && current_user.can_org_admin? then
    +       @suggested_answer = SuggestedAnswer.find(params[:suggested_answer])
    +       @question = @suggested_answer.question
    +       @section = @question.section
    +                @version = @section.version
    +       @phase = @version.phase
    +    @suggested_answer.destroy
    +
    +    respond_to do |format|
    +      format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :edit => 'true'), notice: I18n.t('org_admin.templates.destroyed_message') }
    +      format.json { head :no_content }
    +    end
    +       end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroyversion() + click to toggle source +
    + + +
    + +

    delete a version, sections and questions

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 312
    +def admin_destroyversion
    +if user_signed_in? && current_user.can_org_admin? then
    +       @version = Version.find(params[:version_id])
    +       @phase = @version.phase
    +    @version.destroy
    +
    +    respond_to do |format|
    +      format.html { redirect_to admin_phase_dmptemplate_path(@phase), notice: I18n.t('org_admin.templates.destroyed_message') }
    +      format.json { head :no_content }
    +    end
    +       end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_index() + click to toggle source +
    + + +
    + +

    GET /dmptemplates GET /dmptemplates.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 9
    +def admin_index
    +  if user_signed_in? && current_user.can_org_admin? then
    +      #institutional templates
    +
    +          @dmptemplates_own = Dmptemplate.own_institutional_templates(current_user.organisation_id)
    +
    +          #funders templates
    +
    +          @dmptemplates_funders = Dmptemplate.funders_templates
    +
    +   respond_to do |format|
    +            format.html # index.html.erb
    +
    +         end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_new() + click to toggle source +
    + + +
    + +

    GET /dmptemplates/new GET /dmptemplates/new.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 66
    +def admin_new
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @dmptemplate = Dmptemplate.new
    +
    +          respond_to do |format|
    +            format.html # new.html.erb
    +
    +            format.json { render json: @dmptemplate }
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_phase() + click to toggle source +
    + + +
    + +

    show and edit a phase of the template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 124
    +def admin_phase
    +        if user_signed_in? && current_user.can_org_admin? then
    +
    +                @phase = Phase.find(params[:id])
    +
    +                if !params.has_key?(:version_id) then
    +                        @edit = 'false'
    +                        #check for the most recent published version, if none is available then return the most recent one
    +
    +                        versions = @phase.versions.where('published = ?', true).order('updated_at DESC')
    +                        if versions.any?() then
    +                                @version = versions.first
    +                        else
    +                                @version = @phase.versions.order('updated_at DESC').first
    +                        end
    +                        # When the version_id is passed as an argument
    +
    +                else
    +                        @edit = params[:edit]
    +                        @version = Version.find(params[:version_id])
    +                end
    +
    +                #verify if there are any sections if not create one
    +
    +                @sections = @version.sections
    +                if !@sections.any?() || @sections.count == 0 then
    +                        @section = @version.sections.build
    +                        @section.title = ''
    +                        @section.version_id = params[:version_id]
    +                        @section.number = 1
    +                        @section.organisation_id = current_user.organisation.id
    +                        @section.published = true
    +                        @section.save
    +                end
    +
    +                #verify if section_id has been passed, if so then open that section
    +
    +                if params.has_key?(:section_id) then
    +                        @open = true
    +                        @section_id = params[:section_id].to_i
    +                end
    +
    +                if params.has_key?(:question_id) then
    +                        @question_id = params[:question_id].to_i
    +                end
    +
    +                respond_to do |format|
    +                        format.html
    +                end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_previewphase() + click to toggle source +
    + + +
    + +

    preview a phase

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 173
    +def admin_previewphase
    +        if user_signed_in? && current_user.can_org_admin? then
    +                
    +                @version = Version.find(params[:id])
    +                
    +                        
    +                respond_to do |format|
    +                        format.html
    +                end
    +        end   
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_template() + click to toggle source +
    + + +
    + +

    GET /dmptemplates/1 GET /dmptemplates/1.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 27
    +def admin_template
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @dmptemplate = Dmptemplate.find(params[:id])
    +
    +          respond_to do |format|
    +            format.html # show.html.erb
    +
    +            format.json { render json: @dmptemplate }
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_update() + click to toggle source +
    + + +
    + +

    PUT /dmptemplates/1 PUT /dmptemplates/1.json

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 44
    +def admin_update
    +      if user_signed_in? && current_user.can_org_admin? then
    +              @dmptemplate = Dmptemplate.find(params[:id])
    +              @dmptemplate.description = params["template-desc"]
    +
    +                respond_to do |format|
    +            if @dmptemplate.update_attributes(params[:dmptemplate])
    +              format.html { redirect_to admin_template_dmptemplate_path(params[:dmptemplate]), notice: I18n.t('org_admin.templates.updated_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "edit" }
    +              format.json { render json: @dmptemplate.errors, status: :unprocessable_entity }
    +            end
    +             end
    +      else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +      end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_updatephase() + click to toggle source +
    + + +
    + +

    update a phase of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 228
    +def admin_updatephase
    +        if user_signed_in? && current_user.can_org_admin? then
    +        @phase = Phase.find(params[:id])
    +        @phase.description = params["phase-desc"]
    +
    +    respond_to do |format|
    +      if @phase.update_attributes(params[:phase])
    +        format.html { redirect_to admin_phase_dmptemplate_path(@phase), notice: I18n.t('org_admin.templates.updated_message') }
    +        format.json { head :no_content }
    +      else
    +        format.html { render action: "admin_phase" }
    +        format.json { render json: @phase.errors, status: :unprocessable_entity }
    +      end
    +    end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_updatequestion() + click to toggle source +
    + + +
    + +

    update a question of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 406
    +def admin_updatequestion
    +        if user_signed_in? && current_user.can_org_admin? then
    +               @question = Question.find(params[:id])
    +                        @question.guidance = params["question-guidance-#{params[:id]}"]
    +                        @question.default_value = params["question-default-value-#{params[:id]}"]
    +       @section = @question.section
    +                        @version = @section.version
    +                        @phase = @version.phase
    +
    +                        respond_to do |format|
    +              if @question.update_attributes(params[:question])
    +                format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') }
    +                format.json { head :no_content }
    +              else
    +                format.html { render action: "admin_phase" }
    +                format.json { render json: @question.errors, status: :unprocessable_entity }
    +              end
    +            end
    +                end
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_updatesection() + click to toggle source +
    + + +
    + +

    update a section of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 347
    +def admin_updatesection
    +        if user_signed_in? && current_user.can_org_admin? then
    +               @section = Section.find(params[:id])
    +               @section.description = params["section-desc-#{params[:id]}"]
    +       @version = @section.version
    +                        @phase = @version.phase
    +
    +                        respond_to do |format|
    +              if @section.update_attributes(params[:section])
    +                format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id , :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') }
    +                format.json { head :no_content }
    +              else
    +                format.html { render action: "admin_phase" }
    +                format.json { render json: @section.errors, status: :unprocessable_entity }
    +              end
    +            end
    +                end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_updatesuggestedanswer() + click to toggle source +
    + + +
    + +

    update a suggested answer of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 463
    +def admin_updatesuggestedanswer
    +        if user_signed_in? && current_user.can_org_admin? then
    +               @suggested_answer = SuggestedAnswer.find(params[:id])
    +    @question = @suggested_answer.question
    +    @section = @question.section
    +    @version = @section.version
    +    @phase = @version.phase
    +
    +                        respond_to do |format|
    +              if @suggested_answer.update_attributes(params[:suggested_answer])
    +                format.html { redirect_to admin_phase_dmptemplate_path(:id => @phase.id, :version_id => @version.id, :section_id => @section.id, :question_id => @question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.updated_message') }
    +                format.json { head :no_content }
    +              else
    +                format.html { render action: "admin_phase" }
    +                format.json { render json: @suggested_answer.errors, status: :unprocessable_entity }
    +              end
    +            end
    +                end
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_updateversion() + click to toggle source +
    + + +
    + +

    update a version of a template

    + + + +
    +
    # File app/controllers/dmptemplates_controller.rb, line 262
    +def admin_updateversion
    +        if user_signed_in? && current_user.can_org_admin? then
    +               @version = Version.find(params[:id])
    +    @version.description = params["version-desc"]
    +    @phase = @version.phase
    +
    +    if @version.published && !@phase.dmptemplate.published then
    +        @phase.dmptemplate.published = true
    +    end
    +    
    +    @all_versions = @phase.versions.where('published = ?', true)
    +    @all_versions.each do |v|
    +        if v.id != @version.id && v.published == true then
    +            v.published = false
    +            v.save
    +        end
    +    end
    +
    +            respond_to do |format|
    +              if @version.update_attributes(params[:version])
    +                format.html { redirect_to admin_phase_dmptemplate_path(@phase, :version_id =>  @version.id, :edit => 'false'), notice: I18n.t('org_admin.templates.updated_message') }
    +                format.json { head :no_content }
    +              else
    +                format.html { render action: "admin_phase" }
    +                format.json { render json: @version.errors, status: :unprocessable_entity }
    +              end
    +            end
    +                end
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ExistingUsersController.html b/public/html/ExistingUsersController.html new file mode 100644 index 0000000..a3baca4 --- /dev/null +++ b/public/html/ExistingUsersController.html @@ -0,0 +1,325 @@ + + + + + + +class ExistingUsersController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ExistingUsersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/existing_users_controller.rb, line 2
    +def index
    +        @email = params[:email]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ExportedPlan.html b/public/html/ExportedPlan.html new file mode 100644 index 0000000..e7911e1 --- /dev/null +++ b/public/html/ExportedPlan.html @@ -0,0 +1,846 @@ + + + + + + +class ExportedPlan - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ExportedPlan

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    VALID_FORMATS + +
    + + +
    +
    + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_details() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 71
    +def admin_details
    +  @admin_details ||= self.settings(:export).fields[:admin]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + as_csv() + click to toggle source +
    + + +
    + +

    Export formats

    + + + +
    +
    # File app/models/exported_plan.rb, line 77
    +def as_csv
    +  CSV.generate do |csv|
    +    csv << ["Section","Question","Answer","Selected option(s)","Answered by","Answered at"]
    +    self.sections.each do |section|
    +      self.questions_for_section(section).each do |question|
    +        answer = self.plan.answer(question.id)
    +        options_string = answer.options.collect {|o| o.text}.join('; ')
    +
    +        csv << [section.title, question.text, sanitize_text(answer.text), options_string, answer.try(:user).try(:name), answer.created_at]
    +      end
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + as_txt() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 91
    +def as_txt
    +  output = "#{self.plan.project.title}\n\n#{self.plan.version.phase.title}\n"
    +
    +  self.sections.each do |section|
    +    output += "\n#{section.title}\n"
    +
    +    self.questions_for_section(section).each do |question|
    +      output += "\n#{question.text}\n"
    +      answer = self.plan.answer(question.id, false)
    +
    +      if answer.nil? || answer.text.nil? then
    +        output += "Question not answered.\n"
    +      else
    +        output += answer.options.collect {|o| o.text}.join("\n")
    +        if question.option_comment_display == true then
    +          output += "\n#{sanitize_text(answer.text)}\n"
    +        else
    +          output += "\n"
    +        end  
    +      end
    +    end
    +  end
    +
    +  output
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 46
    +def funder
    +  org = self.plan.project.dmptemplate.try(:organisation)
    +  org.name if org.present? && org.organisation_type.try(:name) == I18n.t('helpers.org_type.funder')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + grant_title() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 30
    +def grant_title
    +  self.plan.project.grant_number
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + institution() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 51
    +def institution
    +  plan.project.organisation.try(:name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + principal_investigator() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 34
    +def principal_investigator
    +  self.plan.project.principal_investigator
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_data_contact() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 38
    +def project_data_contact
    +  self.plan.project.data_contact
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_description() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 42
    +def project_description
    +  self.plan.project.description
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_identifier() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 26
    +def project_identifier
    +  self.plan.project.identifier
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_name() + click to toggle source +
    + + +
    + +

    Getters to match Settings::Dmptemplate::VALID_ADMIN_FIELDS

    + + + +
    +
    # File app/models/exported_plan.rb, line 20
    +def project_name
    +  name = self.plan.project.title
    +  name += " - #{self.plan.title}" if self.plan.project.dmptemplate.phases.count > 1
    +  name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + questions_for_section(section_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 67
    +def questions_for_section(section_id)
    +  questions.where(section_id: section_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + sections() + click to toggle source +
    + + +
    + +

    sections taken from fields settings

    + + + +
    +
    # File app/models/exported_plan.rb, line 56
    +def sections
    +  sections = self.plan.sections
    +
    +  return [] if questions.empty?
    +
    +  section_ids = questions.pluck(:section_id).uniq
    +  sections = sections.select {|section| section_ids.member?(section.id) }
    +
    +  sections.sort_by(&:number)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + questions() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 119
    +def questions
    +  @questions ||= begin
    +    question_settings = self.settings(:export).fields[:questions]
    +
    +    return [] if question_settings.is_a?(Array) && question_settings.empty?
    +
    +    questions = if question_settings.present? && question_settings != :all
    +      Question.where(id: question_settings)
    +    else
    +      Question.where(section_id: self.plan.sections.collect {|s| s.id })
    +    end
    +
    +    questions.order(:number)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + sanitize_text(text) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/exported_plan.rb, line 135
    +def sanitize_text(text)
    +  if (!text.nil?) then ActionView::Base.full_sanitizer.sanitize(text.gsub(/&nbsp;/,"")) end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/FileType.html b/public/html/FileType.html new file mode 100644 index 0000000..749a3b5 --- /dev/null +++ b/public/html/FileType.html @@ -0,0 +1,279 @@ + + + + + + +class FileType - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class FileType

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/FileUpload.html b/public/html/FileUpload.html new file mode 100644 index 0000000..a91679c --- /dev/null +++ b/public/html/FileUpload.html @@ -0,0 +1,279 @@ + + + + + + +class FileUpload - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class FileUpload

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Guidance.html b/public/html/Guidance.html new file mode 100644 index 0000000..f65c3d8 --- /dev/null +++ b/public/html/Guidance.html @@ -0,0 +1,426 @@ + + + + + + +class Guidance - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Guidance

    + +
    +
    Project: +
    +

    DMPonline v4

    +
    Description: +
    +

    This class keeps the information organisations enter to support users when +answering questions. It always belongs to a guidance group class and it +can be linked directly to a question or through one or more themes

    +
    Created: +
    +

    07/07/2014

    +
    Copyright: +
    +

    Digital Curation Centre

    +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + by_organisation(org_id) + click to toggle source +
    + + +
    + +

    all guidance that belong to an organisation

    + + + +
    +
    # File app/models/guidance.rb, line 40
    +def self.by_organisation(org_id)
    +        all_guidance = Guidance.all
    +        org_guidance = Array.new
    +    
    +        all_guidance.each do |guidance|
    +           if guidance.in_group_belonging_to?(org_id) then
    +                        org_guidance << guidance
    +           end
    +        end
    +        
    +        return org_guidance
    +        
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + get_guidance_group_templates?(guidance_group) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/guidance.rb, line 55
    +def get_guidance_group_templates? (guidance_group)
    +                templates = guidancegroups.where("guidance_group_id (?)", guidance_group.id).template 
    +                return templates
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + in_group_belonging_to?(organisation_id) + click to toggle source +
    + + +
    + +

    verifies if one guidance belongs to a org

    + + + +
    +
    # File app/models/guidance.rb, line 29
    +def in_group_belonging_to?(organisation_id)
    +        guidance_groups.each do |guidance_group|
    +                if guidance_group.organisation_id == organisation_id then
    +                        return true
    +                end
    +        end
    +        return false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/GuidanceGroup.html b/public/html/GuidanceGroup.html new file mode 100644 index 0000000..0907393 --- /dev/null +++ b/public/html/GuidanceGroup.html @@ -0,0 +1,404 @@ + + + + + + +class GuidanceGroup - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class GuidanceGroup

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + guidance_groups_excluding(excluded_orgs) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/guidance_group.rb, line 28
    +def self.guidance_groups_excluding(excluded_orgs)
    +        excluded_org_ids = Array.new
    +        excluded_orgs.each do |org|
    +                excluded_org_ids << org.id
    +        end
    +        return_orgs =  GuidanceGroup.where("organisation_id NOT IN (?)", excluded_org_ids)
    +        return return_orgs
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + display_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/guidance_group.rb, line 20
    +def display_name
    +        if organisation.guidance_groups.count > 1
    +                return "#{organisation.name}: #{name}"
    +        else
    +                return organisation.name
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/guidance_group.rb, line 16
    +def to_s
    +        "#{display_name}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/GuidanceGroupsController.html b/public/html/GuidanceGroupsController.html new file mode 100644 index 0000000..7283e1a --- /dev/null +++ b/public/html/GuidanceGroupsController.html @@ -0,0 +1,547 @@ + + + + + + +class GuidanceGroupsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class GuidanceGroupsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_create() + click to toggle source +
    + + +
    + +

    POST /guidance_groups POST /guidance_groups.json

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 34
    +def admin_create
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidance_group = GuidanceGroup.new(params[:guidance_group])
    +          @guidance_group.organisation_id = current_user.organisation_id
    +      
    +          respond_to do |format|
    +            if @guidance_group.save
    +              format.html { redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.created_message') }
    +              format.json { render json: @guidance_group, status: :created, location: @guidance_group }
    +            else
    +              format.html { render action: "new" }
    +              format.json { render json: @guidance_group.errors, status: :unprocessable_entity }
    +            end
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroy() + click to toggle source +
    + + +
    + +

    DELETE /guidance_groups/1 DELETE /guidance_groups/1.json

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 87
    +def admin_destroy
    +      if user_signed_in? && current_user.can_org_admin? then
    +             @guidance_group = GuidanceGroup.find(params[:id])
    +          @guidance_group.destroy
    +      
    +          respond_to do |format|
    +            format.html { redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.destroyed_message') }
    +            format.json { head :no_content }
    +          end
    +             else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +      
    +      end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_edit() + click to toggle source +
    + + +
    + +

    GET /guidance_groups/1/edit

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 55
    +def admin_edit
    +      if user_signed_in? && current_user.can_org_admin? then
    +    @guidance_group = GuidanceGroup.find(params[:id])
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_new() + click to toggle source +
    + + +
    + +

    GET add new guidance groups

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 21
    +    def admin_new
    +if user_signed_in? && current_user.can_org_admin? then
    +        @guidance_group = GuidanceGroup.new
    +           
    +        respond_to do |format|
    +          format.html # new.html.erb
    +
    +          format.json { render json: @guidance }
    +        end
    +    end
    +    end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_show() + click to toggle source +
    + + +
    + +

    GET /guidance_groups/1 GET /guidance_groups/1.json

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 6
    +def admin_show
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidance_group = GuidanceGroup.find(params[:id])
    +      
    +          respond_to do |format|
    +            format.html 
    +            format.json { render json: @guidance_group }
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_update() + click to toggle source +
    + + +
    + +

    PUT /guidance_groups/1 PUT /guidance_groups/1.json

    + + + +
    +
    # File app/controllers/guidance_groups_controller.rb, line 65
    +def admin_update
    +              if user_signed_in? && current_user.can_org_admin? then
    +              @guidance_group = GuidanceGroup.find(params[:id])
    +          @guidance_group.organisation_id = current_user.organisation_id
    +
    +          respond_to do |format|
    +            if @guidance_group.update_attributes(params[:guidance_group])
    +              format.html { redirect_to admin_index_guidance_path(params[:guidance_group]), notice: I18n.t('org_admin.guidance_group.updated_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "edit" }
    +              format.json { render json: @guidance_group.errors, status: :unprocessable_entity }
    +            end
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/GuidancesController.html b/public/html/GuidancesController.html new file mode 100644 index 0000000..7e036ea --- /dev/null +++ b/public/html/GuidancesController.html @@ -0,0 +1,810 @@ + + + + + + +class GuidancesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class GuidancesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_create() + click to toggle source +
    + + +
    + +

    POST /guidances POST /guidances.json

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 155
    +def admin_create
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidance = Guidance.new(params[:guidance])
    +          @guidance.text = params["guidance-text"]
    +          @guidance.question_id = params["question_id"]
    +
    +          respond_to do |format|
    +            if @guidance.save
    +              format.html { redirect_to admin_show_guidance_path(@guidance), notice: I18n.t('org_admin.guidance.created_message') }
    +              format.json { render json: @guidance, status: :created, location: @guidance }
    +            else
    +              format.html { render action: "new" }
    +              format.json { render json: @guidance.errors, status: :unprocessable_entity }
    +            end
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_destroy() + click to toggle source +
    + + +
    + +

    DELETE /guidances/1 DELETE /guidances/1.json

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 202
    +def admin_destroy
    +      if user_signed_in? && current_user.can_org_admin? then
    +             @guidance = Guidance.find(params[:id])
    +          @guidance.destroy
    +
    +          respond_to do |format|
    +            format.html { redirect_to admin_index_guidance_path }
    +            format.json { head :no_content }
    +          end
    +             else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +
    +      end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_edit() + click to toggle source +
    + + +
    + +

    GET /guidances/1/edit

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 112
    +def admin_edit
    +      if user_signed_in? && current_user.can_org_admin? then
    +    @guidance = Guidance.find(params[:id])
    +    @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id)
    +                      @phases = nil
    +                      @dmptemplates.each do |template|
    +                              if @phases.nil? then
    +                                      @phases = template.phases.find(:all,:order => 'number ASC')
    +                              else
    +                                      @phases = @phases + template.phases.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +                      @versions = nil
    +                      @phases.each do |phase|
    +                              if @versions.nil? then
    +                                      @versions = phase.versions.find(:all,:order => 'title ASC')
    +                              else
    +                                      @versions = @versions + phase.versions.find(:all,:order => 'title ASC')
    +                              end
    +                      end
    +                      @sections = nil
    +                      @versions.each do |version|
    +                              if @sections.nil? then
    +                                      @sections = version.sections.find(:all,:order => 'number ASC')
    +                              else
    +                                      @sections = @sections + version.sections.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +                      @questions = nil
    +                      @sections.each do |section|
    +                              if @questions.nil? then
    +                                      @questions = section.questions.find(:all,:order => 'number ASC')
    +                              else
    +                                      @questions = @questions + section.questions.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_index() + click to toggle source +
    + + +
    + +

    GET /guidances GET /guidances.json

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 5
    +def admin_index
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidances = Guidance.by_organisation(current_user.organisation_id)
    +          @guidance_groups = GuidanceGroup.where('organisation_id = ?', current_user.organisation_id )
    +
    +
    +          respond_to do |format|
    +            format.html # index.html.erb
    +
    +            format.json { render json: @guidances }
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/guidances_controller.rb, line 33
    +def admin_new
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidance = Guidance.new
    +                      @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id)
    +                      @phases = nil
    +                      @dmptemplates.each do |template|
    +                              if @phases.nil? then
    +                                      @phases = template.phases.find(:all,:order => 'number ASC')
    +                              else
    +                                      @phases = @phases + template.phases.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +                      @versions = nil
    +                      @phases.each do |phase|
    +                              if @versions.nil? then
    +                                      @versions = phase.versions.find(:all,:order => 'title ASC')
    +                              else
    +                                      @versions = @versions + phase.versions.find(:all,:order => 'title ASC')
    +                              end
    +                      end
    +                      @sections = nil
    +                      @versions.each do |version|
    +                              if @sections.nil? then
    +                                      @sections = version.sections.find(:all,:order => 'number ASC')
    +                              else
    +                                      @sections = @sections + version.sections.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +                      @questions = nil
    +                      @sections.each do |section|
    +                              if @questions.nil? then
    +                                      @questions = section.questions.find(:all,:order => 'number ASC')
    +                              else
    +                                      @questions = @questions + section.questions.find(:all,:order => 'number ASC')
    +                              end
    +                      end
    +          respond_to do |format|
    +            format.html
    +          end
    +      end
    +      end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_show() + click to toggle source +
    + + +
    + +

    GET /guidances/1 GET /guidances/1.json

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 22
    +def admin_show
    +  if user_signed_in? && current_user.can_org_admin? then
    +          @guidance = Guidance.find(params[:id])
    +
    +          respond_to do |format|
    +            format.html # show.html.erb
    +
    +            format.json { render json: @guidance }
    +          end
    + end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_update() + click to toggle source +
    + + +
    + +

    PUT /guidances/1 PUT /guidances/1.json

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 177
    +def admin_update
    +              if user_signed_in? && current_user.can_org_admin? then
    +              @guidance = Guidance.find(params[:id])
    +
    +                      @guidance.text = params["guidance-text"]
    +
    +                      @guidance.question_id = params["question_id"]
    +
    +          respond_to do |format|
    +            if @guidance.update_attributes(params[:guidance])
    +              format.html { redirect_to admin_show_guidance_path(params[:guidance]), notice: I18n.t('org_admin.guidance.updated_message') }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "edit" }
    +              format.json { render json: @guidance.errors, status: :unprocessable_entity }
    +            end
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_phases() + click to toggle source +
    + + +
    + +

    setup variables for use in the dynamic updating

    + + + +
    +
    # File app/controllers/guidances_controller.rb, line 76
    +      def update_phases
    +  # updates phases, versions, sections and questions based on template selected
    +
    +  dmptemplate = Dmptemplate.find(params[:dmptemplate_id])
    +  # map to title and id for use in our options_for_select
    +
    +  @phases = dmptemplate.phases.map{|a| [a.title, a.id]}.insert(0, "Select a phase")
    +  @versions = dmptemplate.versions.map{|s| [s.title, s.id]}.insert(0, "Select a version")
    +  @sections = dmptemplate.sections.map{|s| [s.title, s.id]}.insert(0, "Select a section")
    +  @questions = dmptemplate.questions.map{|s| [s.text, s.id]}.insert(0, "Select a question")
    +
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_questions() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/guidances_controller.rb, line 104
    +def update_questions
    +  # updates songs based on artist selected
    +
    +  section = Section.find(params[:section_id])
    +  @questions = section.questions.map{|s| [s.text, s.id]}.insert(0, "Select a question")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_sections() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/guidances_controller.rb, line 96
    +def update_sections
    +  # updates sections and questions based on version selected
    +
    +  version = Version.find(params[:version_id])
    +  # map to name and id for use in our options_for_select
    +
    +  @sections = version.sections.map{|s| [s.title, s.id]}.insert(0, "Select a section")
    +  @questions = version.questions.map{|s| [s.text, s.id]}.insert(0, "Select a question")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_versions() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/guidances_controller.rb, line 87
    +def update_versions
    +   # updates versions, sections and questions based on phase selected
    +
    +   phase = Phase.find(params[:phase_id])
    +   # map to name and id for use in our options_for_select
    +
    +   @versions = phase.versions.map{|s| [s.title, s.id]}.insert(0, "Select a version")
    +   @sections = phase.sections.map{|s| [s.title, s.id]}.insert(0, "Select a section")
    +   @questions = phase.questions.map{|s| [s.text, s.id]}.insert(0, "Select a question")
    + end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/HomeController.html b/public/html/HomeController.html new file mode 100644 index 0000000..dcc676f --- /dev/null +++ b/public/html/HomeController.html @@ -0,0 +1,363 @@ + + + + + + +class HomeController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class HomeController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + about_us() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/home_controller.rb, line 13
    +def about_us
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/home_controller.rb, line 2
    +def index
    +      if user_signed_in?
    +              name = current_user.name(false)
    +              if name.nil? || name == "" then
    +                      redirect_to edit_user_registration_path
    +              else
    +                      redirect_to projects_url
    +              end
    +      end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Object.html b/public/html/Object.html new file mode 100644 index 0000000..e231136 --- /dev/null +++ b/public/html/Object.html @@ -0,0 +1,326 @@ + + + + + + +class Object - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Object

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + scoped_collection() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/admin/user.rb, line 118
    +def scoped_collection
    +  resource_class.includes(:organisations) # prevents N+1 queries to your database
    +
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Option.html b/public/html/Option.html new file mode 100644 index 0000000..1798432 --- /dev/null +++ b/public/html/Option.html @@ -0,0 +1,325 @@ + + + + + + +class Option - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Option

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/option.rb, line 12
    +def to_s
    +        "#{text}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/OptionWarning.html b/public/html/OptionWarning.html new file mode 100644 index 0000000..921cfe8 --- /dev/null +++ b/public/html/OptionWarning.html @@ -0,0 +1,325 @@ + + + + + + +class OptionWarning - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class OptionWarning

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/option_warning.rb, line 9
    +def to_s
    +        "#{text}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Organisation.html b/public/html/Organisation.html new file mode 100644 index 0000000..d71187f --- /dev/null +++ b/public/html/Organisation.html @@ -0,0 +1,626 @@ + + + + + + +class Organisation - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Organisation

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + orgs_with_parent_of_type(org_type) + click to toggle source +
    + + +
    + +

    retrieves info off a child org

    + + + +
    +
    # File app/models/organisation.rb, line 35
    +def self.orgs_with_parent_of_type(org_type)
    +        parents = OrganisationType.find_by_name(org_type).organisations
    +        children = Array.new
    +        parents.each do |parent|
    +              children += parent.children
    +        end
    +        return children
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + other_organisations() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 45
    +def self.other_organisations
    +        org_types = [I18n.t('helpers.org_type.organisation')]
    +        organisations_list = []
    +        org_types.each do |ot|
    +                new_org_obejct = OrganisationType.find_by_name(ot)
    +
    +                org_with_guidance = GuidanceGroup.joins(new_org_obejct.organisations)
    +
    +                organisations_list = organisations_list + org_with_guidance
    +        end
    +        return organisations_list
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + all_guidance_groups() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 70
    +def all_guidance_groups
    +        ggs = guidance_groups
    +        children.each do |c|
    +                ggs = ggs + c.all_guidance_groups
    +        end
    +        return ggs
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + all_sections(version_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 58
    +def all_sections(version_id)
    +        if parent.nil?
    +                secs = sections.where("version_id = ?", version_id)
    +                if secs.nil? then
    +                        secs = Array.new
    +                end
    +                return secs
    +        else
    +                return sections.find_all_by_version_id(version_id) + parent.all_sections(version_id)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + published_templates() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 95
    +def published_templates
    +        return dmptemplates.find_all_by_published(1)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + root() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 78
    +def root
    +        if parent.nil?
    +                return self
    +        else
    +                return parent.root
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + short_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 26
    +def short_name
    +        if abbreviation.nil? then
    +                return name
    +        else
    +                return abbreviation
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 22
    +def to_s
    +        name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + warning(option_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/organisation.rb, line 86
    +def warning(option_id)
    +        warning = option_warnings.find_by_option_id(option_id)
    +        if warning.nil? && !parent.nil? then
    +                return parent.warning(option_id)
    +        else
    +                return warning
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/OrganisationType.html b/public/html/OrganisationType.html new file mode 100644 index 0000000..1448f7c --- /dev/null +++ b/public/html/OrganisationType.html @@ -0,0 +1,279 @@ + + + + + + +class OrganisationType - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class OrganisationType

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/OrganisationUsersController.html b/public/html/OrganisationUsersController.html new file mode 100644 index 0000000..cd53ddb --- /dev/null +++ b/public/html/OrganisationUsersController.html @@ -0,0 +1,334 @@ + + + + + + +class OrganisationUsersController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class OrganisationUsersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/organisation_users_controller.rb, line 3
    +def admin_index
    +        if user_signed_in? && current_user.can_org_admin? then
    +                
    +                respond_to do |format|
    +                        format.html # index.html.erb
    +
    +                        format.json { render json: @organisation_users }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/OrganisationsController.html b/public/html/OrganisationsController.html new file mode 100644 index 0000000..91d1f12 --- /dev/null +++ b/public/html/OrganisationsController.html @@ -0,0 +1,707 @@ + + + + + + +class OrganisationsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class OrganisationsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_edit() + click to toggle source +
    + + +
    + +

    GET /organisations/1/edit

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 58
    +def admin_edit
    +      if user_signed_in? && current_user.can_org_admin? then
    +      @organisation = Organisation.find(params[:id])
    +  
    +  else
    +              render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +      end 
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_show() + click to toggle source +
    + + +
    + +

    GET /organisations/1 GET /organisations/1.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 43
    +def admin_show
    +      if user_signed_in? && current_user.can_org_admin? then
    +          @organisation = Organisation.find(params[:id])
    +      
    +          respond_to do |format|
    +            format.html # show.html.erb
    +
    +            format.json { render json: @organisation }
    +          end
    +  else
    +                      render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +              end 
    +              
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_update() + click to toggle source +
    + + +
    + +

    PUT /organisations/1 PUT /organisations/1.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 70
    +def admin_update
    +  if user_signed_in? && current_user.can_org_admin? then
    +      @organisation = Organisation.find(params[:id])
    +      @organisation.banner_text = params["org_banner_text"]
    +              
    +              
    +          respond_to do |format|
    +            if @organisation.update_attributes(params[:organisation])
    +              format.html { redirect_to admin_show_organisation_path(params[:id]), notice: I18n.t("admin.org_updated_message")  }
    +              format.json { head :no_content }
    +            else
    +              format.html { render action: "edit" }
    +              format.json { render json: @organisation.errors, status: :unprocessable_entity }
    +            end
    +          end
    +      else
    +        render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +  end         
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + children() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/organisations_controller.rb, line 108
    +        def children
    +                @organisation = Organisation.find(params[:id])
    +                #if user_signed_in? then
    +
    +                children = {}
    +                @organisation.children.each do |child|
    +                        children[child.id] = child.name
    +                end
    +                respond_to do |format|
    +                        format.json { render json: children.to_json }
    +                end
    +#               else
    +
    +#                       render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +
    +#               end
    +
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /organisations POST /organisations.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 26
    +def create
    +  @organisation = Organisation.new(params[:organisation])
    +
    +  respond_to do |format|
    +    if @organisation.save
    +      format.html { redirect_to @organisation, notice: I18n.t("admin.org_created_message") }
    +      format.json { render json: @organisation, status: :created, location: @organisation }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @organisation.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /organisations/1 DELETE /organisations/1.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 92
    +def destroy
    +  @organisation = Organisation.find(params[:id])
    +  @organisation.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to organisations_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /organisations GET /organisations.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 4
    +def index
    +  @organisations = Organisation.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @organisations }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /organisations/new GET /organisations/new.json

    + + + +
    +
    # File app/controllers/organisations_controller.rb, line 15
    +def new
    +  @organisation = Organisation.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @organisation }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + parent() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/organisations_controller.rb, line 102
    +def parent
    +      @organisation = Organisation.find(params[:id])
    +      parent_org = @organisation.find_by {|o| o.parent_id }
    +      return parent_org
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + templates() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/organisations_controller.rb, line 123
    +        def templates
    +                @organisation = Organisation.find(params[:id])
    +                #if user_signed_in? then
    +
    +                templates = {}
    +                @organisation.dmptemplates.each do |template|
    +                        if template.is_published? then
    +                                templates[template.id] = template.title
    +                        end
    +                end
    +                respond_to do |format|
    +                        format.json { render json: templates.to_json }
    +                end
    +#               else
    +
    +#                       render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +
    +#               end
    +
    +        end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Page.html b/public/html/Page.html new file mode 100644 index 0000000..a4a8cea --- /dev/null +++ b/public/html/Page.html @@ -0,0 +1,279 @@ + + + + + + +class Page - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Page

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/PagesController.html b/public/html/PagesController.html new file mode 100644 index 0000000..b067c7c --- /dev/null +++ b/public/html/PagesController.html @@ -0,0 +1,561 @@ + + + + + + +class PagesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class PagesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /pages POST /pages.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 42
    +def create
    +  @page = Page.new(params[:page])
    +
    +  respond_to do |format|
    +    if @page.save
    +      format.html { redirect_to @page, notice: 'Page was successfully created.' }
    +      format.json { render json: @page, status: :created, location: @page }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @page.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /pages/1 DELETE /pages/1.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 74
    +def destroy
    +  @page = Page.find(params[:id])
    +  @page.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to pages_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /pages/1/edit

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 36
    +def edit
    +  @page = Page.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /pages GET /pages.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 4
    +def index
    +  @pages = Page.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @pages }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /pages/new GET /pages/new.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 26
    +def new
    +  @page = Page.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @page }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /pages/1 GET /pages/1.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 15
    +def show
    +  @page = Page.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @page }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /pages/1 PUT /pages/1.json

    + + + +
    +
    # File app/controllers/pages_controller.rb, line 58
    +def update
    +  @page = Page.find(params[:id])
    +
    +  respond_to do |format|
    +    if @page.update_attributes(params[:page])
    +      format.html { redirect_to @page, notice: 'Page was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @page.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/PasswordsController.html b/public/html/PasswordsController.html new file mode 100644 index 0000000..3364f85 --- /dev/null +++ b/public/html/PasswordsController.html @@ -0,0 +1,325 @@ + + + + + + +class PasswordsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class PasswordsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Protected Instance Methods

    + + +
    + +
    + after_resetting_password_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/passwords_controller.rb, line 5
    +    def after_resetting_password_path_for(resource)
    +    root_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Phase.html b/public/html/Phase.html new file mode 100644 index 0000000..c5491a9 --- /dev/null +++ b/public/html/Phase.html @@ -0,0 +1,457 @@ + + + + + + +class Phase - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Phase

    + +
    +
    Project: +
    +

    DMPonline v4

    +
    Description: +
    +

    This model describes informmation about the phase of a plan, it's +title, order of display and which template it belongs to.

    +
    Created: +
    +

    03/09/2014

    +
    Copyright: +
    +

    Digital Curation Centre

    +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + has_sections() + click to toggle source +
    + + +
    + +

    verify if a phase has a published version or a version with one or more +sections

    + + + +
    +
    # File app/models/phase.rb, line 44
    +def has_sections
    +        versions = self.versions.where('published = ?', true).order('updated_at DESC')
    +        if versions.any? then
    +                version = versions.first
    +                if !version.sections.empty? then
    +                        has_section = true
    +                else
    +                        has_section = false
    +                end  
    +        else
    +                version = self.versions.order('updated_at DESC').first 
    +                if !version.sections.empty? then
    +                        has_section = true
    +                else
    +                        has_section = false
    +                end  
    +        end
    +        return has_section
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + latest_published_version() + click to toggle source +
    + + +
    + +

    Verify if this phase has any published versions

    + + + +
    +
    # File app/models/phase.rb, line 34
    +def latest_published_version
    +        versions.order("number DESC").each do |version|
    +                if version.published then
    +                        return version
    +                end
    +        end
    +        return nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + latest_version() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/phase.rb, line 29
    +def latest_version
    +        return versions.order("number DESC").last
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/phase.rb, line 25
    +def to_s
    +        "#{title}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Plan.html b/public/html/Plan.html new file mode 100644 index 0000000..9f0b894 --- /dev/null +++ b/public/html/Plan.html @@ -0,0 +1,1393 @@ + + + + + + +class Plan - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Plan

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    A4_PAGE_HEIGHT + +
    + + +
    A4_PAGE_WIDTH + +
    + + +
    FONT_HEIGHT_CONVERSION_FACTOR + +
    + + +
    FONT_WIDTH_HEIGHT_RATIO + +
    + + +
    ROUNDING + +
    + + +
    +
    + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + add_guidance_to_array(guidance_array, guidance_group, theme, guidance) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 119
    +def add_guidance_to_array(guidance_array, guidance_group, theme, guidance)
    +        
    +        if guidance_array[guidance_group].nil? then
    +                guidance_array[guidance_group] = {}
    +        end
    +        if theme.nil? then
    +                if guidance_array[guidance_group]["no_theme"].nil? then
    +                        guidance_array[guidance_group]["no_theme"] = []
    +                end
    +                if !guidance_array[guidance_group]["no_theme"].include?(guidance) then
    +                        guidance_array[guidance_group]["no_theme"].push(guidance)
    +                end
    +        else
    +                if guidance_array[guidance_group][theme].nil? then
    +                        guidance_array[guidance_group][theme] = []
    +                end
    +                if !guidance_array[guidance_group][theme].include?(guidance) then
    +                        guidance_array[guidance_group][theme].push(guidance)
    +                end
    +        end
    +        
    +return guidance_array
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + administerable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 168
    +def administerable_by(user_id)
    +        return project.readable_by(user_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + answer(qid, create_if_missing = true) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 53
    +def answer(qid, create_if_missing = true)
    +        answer = answers.where(:question_id => qid).order("created_at DESC").first
    +        question = Question.find(qid)
    +        if answer.nil? && create_if_missing then
    +                answer = Answer.new
    +                answer.plan_id = id
    +                answer.question_id = qid
    +                answer.text = question.default_value
    +                default_options = Array.new
    +                question.options.each do |option|
    +                        if option.is_default
    +                                default_options << option
    +                        end
    +                end
    +                answer.options = default_options
    +        end
    +        return answer
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + delete_recent_locks(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 291
    +def delete_recent_locks(user_id)
    +        plan_sections.where(:user_id => user_id).each do |lock|
    +                lock.delete
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + details() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 230
    +def details
    +        details = {
    +                "project_title" => project.title,
    +                "phase_title" => version.phase.title,
    +                "sections" => {}
    +        }
    +        sections.sort_by(&:"number").each do |s|
    +                details["sections"][s.number] = {}
    +                details["sections"][s.number]["title"] = s.title
    +                details["sections"][s.number]["questions"] = {}
    +                s.questions.order("number").each do |q|
    +                        details["sections"][s.number]["questions"][q.number] = {}
    +                        details["sections"][s.number]["questions"][q.number]["question_text"] = q.text
    +                        answer = answer(q.id, false)
    +                        if ! answer.nil? then
    +            q_format = q.question_format
    +                                if (q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") ||
    +                                q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown")) then
    +                                        details["sections"][s.number]["questions"][q.number]["selections"] = {}
    +                                        answer.options.each do |o|
    +                                                details["sections"][s.number]["questions"][q.number]["selections"][o.number] = o.text
    +                                        end
    +                                end
    +                                details["sections"][s.number]["questions"][q.number]["answer_text"] = answer.text
    +                        end
    +                end
    +        end
    +        return details
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + dmptemplate() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 36
    +def dmptemplate
    +        self.project.try(:dmptemplate) || Dmptemplate.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + editable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 156
    +def editable_by(user_id)
    +        return project.editable_by(user_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + guidance_for_question(question) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 81
    +def guidance_for_question(question)
    +        guidances = {}
    +        # If project org isn't nil, get guidance by theme from any "non-subset" groups belonging to project org
    +
    +        unless project.organisation.nil? then
    +                project.organisation.guidance_groups.each do |group|
    +                        if !group.optional_subset && (group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0) then
    +                                group.guidances.each do |guidance|
    +                                        guidance.themes.where("id IN (?)", question.theme_ids).each do |theme|
    +                                                guidances = self.add_guidance_to_array(guidances, group, theme, guidance)
    +                                        end
    +                                end
    +                        end
    +                end
    +        end
    +
    +        # Get guidance by theme from any guidance groups selected on creation
    +
    +        project.guidance_groups.each do |group|
    +                if group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0 then
    +                        group.guidances.each do |guidance|
    +                                guidance.themes.where("id IN (?)", question.theme_ids).each do |theme|
    +                                        guidances = self.add_guidance_to_array(guidances, group, theme, guidance)
    +                                end
    +                        end
    +                end 
    +end
    +        
    +        # Get guidance by question where guidance group was selected on creation or if group is organisation default
    +
    +        question.guidances.each do |guidance|
    +                guidance.guidance_groups.each do |group|
    +                        if (group.organisation == project.organisation && !group.optional_subset) || project.guidance_groups.include?(group) then
    +                                guidances = self.add_guidance_to_array(guidances, group, nil, guidance)
    +                        end
    +    end
    +        end
    +
    +        return guidances
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + latest_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 321
    +def latest_update
    +        if answers.any? then
    +                last_answered = answers.order("updated_at DESC").first.updated_at
    +                if last_answered > updated_at then
    +                        return last_answered
    +                else
    +                        return updated_at
    +                end
    +        else
    +                return updated_at
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + lock_all_sections(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 279
    +def lock_all_sections(user_id)
    +        sections.each do |s|
    +                lock_section(s.id, user_id, 1800)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + lock_section(section_id, user_id, release_time = 60) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 297
    +def lock_section(section_id, user_id, release_time = 60)
    +        status = locked(section_id, user_id)
    +        if ! status["locked"] then
    +                plan_section = PlanSection.new
    +                plan_section.plan_id = id
    +                plan_section.section_id = section_id
    +                plan_section.release_time = Time.now + release_time.seconds
    +                plan_section.user_id = user_id
    +                plan_section.save
    +        elsif status["current_user"] then
    +                plan_section = PlanSection.find(status["id"])
    +                plan_section.release_time = Time.now + release_time.seconds
    +                plan_section.save
    +        else
    +                return false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + locked(section_id, user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 260
    +def locked(section_id, user_id)
    +        plan_section = plan_sections.where("section_id = ? AND user_id != ? AND release_time > ?", section_id, user_id, Time.now).last
    +        if plan_section.nil? then
    +                status = {
    +                        "locked" => false,
    +                        "locked_by" => nil,
    +                        "timestamp" => nil,
    +                        "id" => nil
    +                }
    +        else
    +                status = {
    +                        "locked" => true,
    +                        "locked_by" => plan_section.user.name,
    +                        "timestamp" => plan_section.updated_at,
    +                        "id" => plan_section.id
    +                }
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + readable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 160
    +def readable_by(user_id)
    +        if project.nil?
    +                return false
    +        else
    +                return project.readable_by(user_id)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + section_answers(section_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 334
    +def section_answers(section_id)
    +        section = Section.find(section_id)
    +        section_questions = Array.new
    +        counter = 0
    +        section.questions.each do |q|
    +                section_questions[counter] = {}
    +                section_questions[counter]["id"] = q.id
    +                #section_questions[counter]["multiple_choice"] = q.multiple_choice
    +
    +                q_answer = answer(q.id, false)
    +                if q_answer.nil? then
    +                        section_questions[counter]["answer_id"] = nil
    +                        if q.suggested_answers.find_by_organisation_id(project.organisation_id).nil? then
    +                                section_questions[counter]["answer_text"] = ""
    +                        else
    +                                section_questions[counter]["answer_text"] = q.default_value
    +                        end
    +                        section_questions[counter]["answer_timestamp"] = nil
    +                        section_questions[counter]["answer_options"] = Array.new
    +                else
    +                        section_questions[counter]["answer_id"] = q_answer.id
    +                        section_questions[counter]["answer_text"] = q_answer.text
    +                        section_questions[counter]["answer_timestamp"] = q_answer.created_at
    +                        section_questions[counter]["answer_options"] = q_answer.options.pluck(:id)
    +                end
    +                counter = counter + 1
    +        end
    +        return section_questions
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + sections() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 72
    +def sections
    +        unless project.organisation.nil? then
    +                sections = version.global_sections + project.organisation.all_sections(version_id)
    +        else
    +                sections = version.global_sections
    +        end
    +        return sections.uniq.sort_by &:number
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + settings(key) + click to toggle source +
    + + +
    + +

    Proxy through to the template settings (or defaults if this plan +doesn't have an associated template) if there are no settings stored +for this plan. `key` is required by rails-settings, so it's required +here, too.

    + + + +
    +
    # File app/models/plan.rb, line 29
    +def settings(key)
    +        self_settings = self.super_settings(key)
    +        return self_settings if self_settings.value?
    +
    +        self.dmptemplate.settings(key)
    +end
    +
    + +
    + + +
    + Also aliased as: super_settings +
    + + + +
    + + +
    + +
    + status() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 172
    +def status
    +        status = {
    +                "num_questions" => 0,
    +                "num_answers" => 0,
    +                "sections" => {},
    +                "questions" => {},
    +                "space_used" => 0 # percentage of available space in pdf used
    +
    +        }
    +
    +        space_used = height_of_text(self.project.title, 2, 2)
    +
    +        sections.each do |s|
    +                space_used += height_of_text(s.title, 1, 1)
    +                section_questions = 0
    +                section_answers = 0
    +                status["sections"][s.id] = {}
    +                status["sections"][s.id]["questions"] = Array.new
    +                s.questions.each do |q|
    +                        status["num_questions"] += 1
    +                        section_questions += 1
    +                        status["sections"][s.id]["questions"] << q.id
    +                        status["questions"][q.id] = {}
    +                        answer = answer(q.id, false)
    +
    +                        space_used += height_of_text(q.text) unless q.text == s.title
    +                        space_used += height_of_text(answer.try(:text) || I18n.t('helpers.plan.export.pdf.question_not_answered'))
    +
    +                        if ! answer.nil? then
    +                                status["questions"][q.id] = {
    +                                        "answer_id" => answer.id,
    +                                        "answer_created_at" => answer.created_at.to_i,
    +                                        "answer_text" => answer.text,
    +                                        "answer_option_ids" => answer.option_ids,
    +                                        "answered_by" => answer.user.name
    +                                }
    +            q_format = q.question_format
    +                                status["num_answers"] += 1 if (q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") ||
    +                                q_format.title == I18n.t("helpers.radio_buttons") || q_format.title == I18n.t("helpers.dropdown")) || answer.text.present?
    +                                section_answers += 1
    +                                #TODO: include selected options in space estimate
    +
    +                        else
    +                                status["questions"][q.id] = {
    +                                        "answer_id" => nil,
    +                                        "answer_created_at" => nil,
    +                                        "answer_text" => nil,
    +                                        "answer_option_ids" => nil,
    +                                        "answered_by" => nil
    +                                }
    +                        end
    +                        status["sections"][s.id]["num_questions"] = section_questions
    +                        status["sections"][s.id]["num_answers"] = section_answers
    +                end
    +        end
    +
    +        status['space_used'] = estimate_space_used(space_used)
    +        return status
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + super_settings(key) + click to toggle source +
    + + +
    + + + + + +
    + + + + +
    + Alias for: settings +
    + +
    + + +
    + +
    + title() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 40
    +def title
    +        logger.debug "Title in settings: #{self.settings(:export).title}"
    +        if self.settings(:export).title == ""
    +    if !self.version.nil? && !self.version.phase.nil? && !self.version.phase.title? then
    +        return self.version.phase.title
    +    else
    +        return "DMP title"
    +                end
    +        else
    +                return self.settings(:export).title
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unlock_all_sections(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 285
    +def unlock_all_sections(user_id)
    +        plan_sections.where(:user_id => user_id).order("created_at DESC").each do |lock|
    +                lock.delete
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unlock_section(section_id, user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 315
    +def unlock_section(section_id, user_id)
    +        plan_sections.where(:section_id => section_id, :user_id => user_id).order("created_at DESC").each do |lock|
    +                lock.delete
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + warning(option_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/plan.rb, line 148
    +def warning(option_id)
    +        if project.organisation.nil?
    +                return nil
    +        else
    +                return project.organisation.warning(option_id)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + estimate_space_used(used_height) + click to toggle source +
    + + +
    + +

    Based on the height of the text gathered so far and the available vertical +space of the pdf, estimate a percentage of how much space has been used. +This is highly dependent on the layout in the pdf. A more accurate approach +would be to render the pdf and check how much space had been used, but that +could be very slow. NOTE: This is only an estimate, rounded up to the +nearest 5%; it is intended for guidance when editing plan data, not to be +100% accurate.

    + + + +
    +
    # File app/models/plan.rb, line 372
    +def estimate_space_used(used_height)
    +        @formatting ||= self.settings(:export).formatting
    +
    +        return 0 unless @formatting[:font_size] > 0
    +
    +        margin_height    = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i
    +        page_height      = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait
    +
    +        available_height = page_height * self.dmptemplate.settings(:export).max_pages
    +
    +        percentage = (used_height / available_height) * 100
    +        (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five
    +
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + height_of_text(text, font_size_inc = 0, vertical_margin = 0) + click to toggle source +
    + + +
    + +

    Take a guess at the vertical height (in mm) of the given text based on the +font-size and left/right margins stored in the plan's settings. This +assumes a fixed-width for each glyph, which is obviously incorrect for the +font-face choices available; the idea is that they'll hopefully average +out to that in the long-run. Allows for hinting different font sizes +(offset from base via font_size_inc) and vertical margins (i.e. for heading +text)

    + + + +
    +
    # File app/models/plan.rb, line 392
    +def height_of_text(text, font_size_inc = 0, vertical_margin = 0)
    +        @formatting     ||= self.settings(:export).formatting
    +        @margin_width   ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i
    +        @base_font_size ||= @formatting[:font_size]
    +
    +        return 0 unless @base_font_size > 0
    +
    +        font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc)
    +        font_width  = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height
    +
    +        leading     = font_height / 2
    +
    +        chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait
    +
    +        num_lines = (text.length / chars_in_line).ceil
    +
    +        (num_lines * font_height) + vertical_margin + leading
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/PlanSection.html b/public/html/PlanSection.html new file mode 100644 index 0000000..563df5e --- /dev/null +++ b/public/html/PlanSection.html @@ -0,0 +1,279 @@ + + + + + + +class PlanSection - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class PlanSection

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/PlansController.html b/public/html/PlansController.html new file mode 100644 index 0000000..6992368 --- /dev/null +++ b/public/html/PlansController.html @@ -0,0 +1,833 @@ + + + + + + +class PlansController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class PlansController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + answer() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 142
    +def answer
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.readable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.json { render json: @plan.answer(params[:q_id], false).to_json(:include => :options) }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + delete_recent_locks() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 74
    +def delete_recent_locks
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                        if @plan.delete_recent_locks(current_user.id)
    +                                format.html { render action: "edit" }
    +                                format.json { head :no_content }
    +                        else
    +                                format.html { render action: "edit" }
    +                                format.json { render json: @plan.errors, status: :unprocessable_entity }
    +                        end
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /plans/1/edit

    + + + +
    +
    # File app/controllers/plans_controller.rb, line 6
    +    def edit
    +            @plan = Plan.find(params[:id])
    +    
    +   
    +if !user_signed_in? then
    +  respond_to do |format|
    +                            format.html { redirect_to edit_user_registration_path }
    +                    end
    +            elsif !@plan.readable_by(current_user.id) then
    +                    respond_to do |format|
    +                            format.html { redirect_to projects_url, notice: "This account does not have access to that plan." }
    +                    end
    +            end
    +    end
    +
    + +
    + + + + +
    + + +
    + +
    + export() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 164
    +def export
    +        @plan = Plan.find(params[:id])
    +
    +        if user_signed_in? && @plan.readable_by(current_user.id) then
    +                @exported_plan = ExportedPlan.new.tap do |ep|
    +                        ep.plan = @plan
    +                        ep.user = current_user
    +                        ep.format = request.format.try(:symbol)
    +                        plan_settings = @plan.settings(:export)
    +
    +                        Settings::Dmptemplate::DEFAULT_SETTINGS.each do |key, value|
    +                                ep.settings(:export).send("#{key}=", plan_settings.send(key))
    +                        end
    +                end
    +
    +                @exported_plan.save! # FIXME: handle invalid request types without erroring?
    +
    +                file_name = @exported_plan.project_name
    +
    +                respond_to do |format|
    +        format.html
    +        format.xml
    +        format.json
    +        format.csv  { send_data @exported_plan.as_csv, filename: "#{file_name}.csv" }
    +        format.text { send_data @exported_plan.as_txt, filename: "#{file_name}.txt" }
    +                        format.docx { headers["Content-Disposition"] = "attachment; filename=\"#{file_name}.docx\""}
    +        format.pdf do
    +            @formatting = @plan.settings(:export).formatting
    +            render pdf: file_name,
    +                                 margin: @formatting[:margin],
    +                                 footer: {
    +                                   center:    t('helpers.plan.export.pdf.generated_by'),
    +                                   font_size: 8,
    +                                   spacing:   (@formatting[:margin][:bottom] / 2) - 4,
    +                                   right:     '[page] of [topage]'
    +                                 }
    +                  end
    +                end
    +        elsif !user_signed_in? then
    +       respond_to do |format|
    +                        format.html { redirect_to edit_user_registration_path }
    +                end
    +        elsif !@plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.html { redirect_to projects_url, notice: "This account does not have access to that plan." }
    +                end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + lock_section() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 108
    +def lock_section
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                        if @plan.lock_section(params[:section_id], current_user.id)
    +                                format.html { render action: "edit" }
    +                                format.json { head :no_content }
    +                        else
    +                                format.html { render action: "edit" }
    +                                format.json { render json: @plan.errors, status: :unprocessable_entity }
    +                        end
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + locked() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 63
    +def locked
    +        @plan = Plan.find(params[:id])
    +        if !@plan.nil? && user_signed_in? && @plan.readable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.json { render json: @plan.locked(params[:section_id],current_user.id) }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + section_answers() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 52
    +def section_answers
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.readable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.json { render json: @plan.section_answers(params[:section_id]) }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + status() + click to toggle source +
    + + +
    + +

    GET /status/1.json

    + + + +
    +
    # File app/controllers/plans_controller.rb, line 41
    +def status
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.readable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.json { render json: @plan.status }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unlock_all_sections() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 91
    +def unlock_all_sections
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                        if @plan.unlock_all_sections(current_user.id)
    +                                format.html { render action: "edit" }
    +                                format.json { head :no_content }
    +                        else
    +                                format.html { render action: "edit" }
    +                                format.json { render json: @plan.errors, status: :unprocessable_entity }
    +                        end
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unlock_section() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 125
    +def unlock_section
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                        if @plan.unlock_section(params[:section_id], current_user.id)
    +                                format.html { render action: "edit" }
    +                                format.json { head :no_content }
    +                        else
    +                                format.html { render action: "edit" }
    +                                format.json { render json: @plan.errors, status: :unprocessable_entity }
    +                        end
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /plans/1 PUT /plans/1.json

    + + + +
    +
    # File app/controllers/plans_controller.rb, line 23
    +def update
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.editable_by(current_user.id) then
    +                respond_to do |format|
    +                if @plan.update_attributes(params[:plan])
    +                        format.html { redirect_to @plan, notice: 'Plan was successfully updated.' }
    +                        format.json { head :no_content }
    +                else
    +                        format.html { render action: "edit" }
    +                        format.json { render json: @plan.errors, status: :unprocessable_entity }
    +                end
    +        end
    +else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + warning() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/plans_controller.rb, line 153
    +def warning
    +        @plan = Plan.find(params[:id])
    +        if user_signed_in? && @plan.readable_by(current_user.id) then
    +                respond_to do |format|
    +                        format.json { render json: @plan.warning(params[:option_id]) }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/PlansHelper.html b/public/html/PlansHelper.html new file mode 100644 index 0000000..6373cd5 --- /dev/null +++ b/public/html/PlansHelper.html @@ -0,0 +1,427 @@ + + + + + + +module PlansHelper - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module PlansHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + plan_settings_indicator(plan) + click to toggle source +
    + + +
    + +

    Shows whether the user has default, template-default or custom settings for +the given plan.

    + + + +
    +
    # File app/helpers/plans_helper.rb, line 45
    +def plan_settings_indicator(plan)
    +  plan_settings     = plan.super_settings(:export)
    +  template_settings = plan.project.dmptemplate.try(:settings, :export)
    +
    +  key = if plan_settings.try(:value?)
    +    plan_settings.formatting == template_settings.formatting ? 'template_formatting' : 'custom_formatting'
    +  elsif template_settings.try(:value?)
    +    'template_formatting'
    +  else
    +    'default_formatting'
    +  end
    +
    +  content_tag(:small, t("helpers.settings.plans.#{key}"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_list_body(column, project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/plans_helper.rb, line 13
    +def project_list_body(column, project)
    +  klass, content = case column
    +    when :name
    +      [ 'dmp_td_big', link_to(project.title, project_path(project), class: 'dmp_table_link') ]
    +    when :owner
    +      user = project.owner
    +      text = if user.nil?
    +        'Unknown'
    +      elsif user == current_user
    +        t('helpers.me')
    +      else
    +        user.name
    +      end
    +
    +      [ 'tmp_td_small', text ]
    +    when :shared
    +      shared_num = project.project_groups.count - 1
    +      text = shared_num > 0 ? (t('helpers.yes') + " (with #{shared_num} people) ") : t('helpers.no')
    +      [ 'dmp_td_small', text ]
    +    when :last_edited
    +      [ 'dmp_td_small', l(project.latest_update.to_date, formats: :short) ]
    +    when :description
    +      [ 'dmp_td_medium', (project.try(column) || 'Unknown') ]
    +    else
    +      [ 'dmp_td_small', (project.try(column) || 'Unknown') ]
    +  end
    +
    +  content_tag(:td, content, class: klass)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_list_head(column) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/plans_helper.rb, line 3
    +def project_list_head(column)
    +  klass = case column
    +    when :name  then :dmp_th_big
    +    when :description then :dmp_th_big
    +    else :dmp_th_small
    +  end
    +
    +  content_tag(:th, t("helpers.project.columns.#{column}"), class: klass)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Project.html b/public/html/Project.html new file mode 100644 index 0000000..ca0dd35 --- /dev/null +++ b/public/html/Project.html @@ -0,0 +1,1262 @@ + + + + + + +class Project - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Project

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + projects_for_user(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 142
    +def self.projects_for_user(user_id)
    +        projects = Array.new
    +        groups = ProjectGroup.where("user_id = ?", user_id)
    +        unless groups.nil? then
    +                groups.each do |group|
    +                        unless group.project.nil? then
    +                                projects << group.project
    +                        end
    +                end
    +        end
    +        return projects
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + administerable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 115
    +def administerable_by(user_id)
    +        user = project_groups.find_by_user_id(user_id)
    +        if (! user.nil?) && user.project_administrator then
    +                return true
    +        else
    +                return false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + assign_administrator(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 111
    +def assign_administrator(user_id)
    +        add_user(user_id, true, true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + assign_creator(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 99
    +def assign_creator(user_id)
    +        add_user(user_id, true, true, true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + assign_editor(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 103
    +def assign_editor(user_id)
    +        add_user(user_id, true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + assign_reader(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 107
    +def assign_reader(user_id)
    +        add_user(user_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + created_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 155
    +def created_by(user_id)
    +        user = project_groups.find_by_user_id(user_id)
    +        if (! user.nil?) && user.project_creator then
    +                return true
    +        else
    +                return false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + editable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 124
    +def editable_by(user_id)
    +        user = project_groups.find_by_user_id(user_id)
    +        if (! user.nil?) && user.project_editor then
    +                return true
    +        else
    +                return false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 39
    +def funder
    +        if dmptemplate.nil? then
    +                return nil
    +        end
    +        template_org = dmptemplate.organisation
    +        if template_org.organisation_type.name == I18n.t('helpers.org_type.funder').downcase
    +                return template_org
    +        else
    +                return nil
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 27
    +def funder_id
    +        if dmptemplate.nil? then
    +                return nil
    +        end
    +        template_org = dmptemplate.organisation
    +        if template_org.organisation_type.name == I18n.t('helpers.org_type.funder').downcase
    +                return template_org.id
    +        else
    +                return nil
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder_id=(new_funder_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 18
    +def funder_id=(new_funder_id)
    +        if new_funder_id != "" then
    +                new_funder = Organisation.find(new_funder_id);
    +                if new_funder.dmptemplates.count == 1 then
    +                        dmptemplate = new_funder.dmptemplates.first
    +                end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 51
    +def funder_name
    +        if self.funder.nil?
    +                return read_attribute(:funder_name)
    +        else
    +                return self.funder.name
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + funder_name=(new_funder_name) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 59
    +def funder_name=(new_funder_name)
    +        write_attribute(:funder_name, new_funder_name)
    +        org_table = Organisation.arel_table
    +        existing_org = Organisation.where(org_table[:name].matches(new_funder_name))
    +        if existing_org.nil?
    +                existing_org = Organisation.where(org_table[:abbreviation].matches(new_funder_name))
    +        end
    +        unless existing_org.empty?
    +                self.funder_id=existing_org.id
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + institution_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 77
    +def institution_id
    +        if organisation.nil?
    +                return nil
    +        else
    +                return organisation.root.id
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + institution_id=(new_institution_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 71
    +def institution_id=(new_institution_id)
    +        if organisation.nil? then
    +                self.organisation_id = new_institution_id
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_edited() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 183
    +def last_edited
    +        self.latest_update.to_date
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + latest_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 164
    +def latest_update
    +        latest_update = updated_at
    +        plans.each do |plan|
    +                if plan.latest_update > latest_update then
    +                        latest_update = plan.latest_update
    +                end
    +        end
    +        return latest_update
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + name() + click to toggle source +
    + + +
    + +

    Getters to match 'My plans' columns

    + + + +
    +
    # File app/models/project.rb, line 175
    +def name
    +        self.title
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + owner() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 179
    +def owner
    +        self.project_groups.find_by_project_creator(true).try(:user)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + readable_by(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 133
    +def readable_by(user_id)
    +        user = project_groups.find_by_user_id(user_id)
    +        if (! user.nil?) then
    +                return true
    +        else
    +                return false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + shared() + click to toggle source +
    + + +
    + + + + + +
    + + + + +
    + Alias for: shared? +
    + +
    + + +
    + +
    + shared?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 187
    +def shared?
    +        self.project_groups.count > 1
    +end
    +
    + +
    + + +
    + Also aliased as: shared +
    + + + +
    + + +
    + +
    + template_owner() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 193
    +def template_owner
    +        self.dmptemplate.try(:organisation).try(:abbreviation)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unit_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 91
    +def unit_id
    +        if organisation.nil? || organisation.parent_id.nil?
    +                return nil
    +        else
    +                return organisation_id
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unit_id=(new_unit_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 85
    +def unit_id=(new_unit_id)
    +        unless new_unit_id.nil? ||new_unit_id == ""
    +                self.organisation_id = new_unit_id
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + add_user(user_id, is_editor = false, is_administrator = false, is_creator = false) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 199
    +def add_user(user_id, is_editor = false, is_administrator = false, is_creator = false)
    +        group = ProjectGroup.new
    +        group.user_id = user_id
    +        group.project_creator = is_creator
    +        group.project_editor = is_editor
    +        group.project_administrator = is_administrator
    +        project_groups << group
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create_plans() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 208
    +def create_plans
    +        dmptemplate.phases.each do |phase|
    +                latest_published_version = phase.latest_published_version
    +                unless latest_published_version.nil?
    +                        new_plan = Plan.new
    +                        new_plan.version = latest_published_version
    +                        plans << new_plan
    +                end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ProjectGroup.html b/public/html/ProjectGroup.html new file mode 100644 index 0000000..70c5421 --- /dev/null +++ b/public/html/ProjectGroup.html @@ -0,0 +1,441 @@ + + + + + + +class ProjectGroup - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectGroup

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + access_level() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project_group.rb, line 21
    +def access_level
    +        if project_administrator then
    +                return 3
    +        elsif project_editor then
    +                return 2
    +        else
    +                return 1
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + access_level=(new_access_level) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project_group.rb, line 31
    +def access_level=(new_access_level)
    +        new_access_level = new_access_level.to_i
    +        if new_access_level >= 3 then
    +                project_administrator = true
    +        else
    +                project_administrator = false
    +        end
    +        if new_access_level >= 2 then
    +                project_editor = true
    +        else
    +                project_editor = false
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + email() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project_group.rb, line 9
    +def email
    +        unless user.nil? 
    +                return user.email
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + email=(new_email) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project_group.rb, line 15
    +def email=(new_email)
    +        unless User.find_by_email(email).nil? then
    +                user = User.find_by_email(email)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ProjectGroupsController.html b/public/html/ProjectGroupsController.html new file mode 100644 index 0000000..96cea38 --- /dev/null +++ b/public/html/ProjectGroupsController.html @@ -0,0 +1,473 @@ + + + + + + +class ProjectGroupsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectGroupsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/project_groups_controller.rb, line 3
    +def create
    +        @project_group = ProjectGroup.new(params[:project_group])
    +        access_level = params[:project_group][:access_level].to_i
    +        if access_level >= 3 then
    +                @project_group.project_administrator = true
    +        end
    +        if access_level >= 2 then
    +                @project_group.project_editor = true
    +        end
    +        if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then
    +                respond_to do |format|
    +                        if params[:project_group][:email].present? && params[:project_group][:email].length > 0 then
    +                                message = 'User added to project'
    +                                if @project_group.save
    +                                        if @project_group.user.nil? then
    +                                                if User.find_by_email(params[:project_group][:email]).nil? then
    +                                                        User.invite!(:email => params[:project_group][:email])
    +                                                        message = 'Invitation issued successfully.'
    +                                                        @project_group.user = User.find_by_email(params[:project_group][:email])
    +                                                        @project_group.save
    +                                                else
    +                                                        @project_group.user = User.find_by_email(params[:project_group][:email])
    +                                                        @project_group.save
    +                                                        UserMailer.sharing_notification(@project_group).deliver
    +                                                        logger.debug("Email sent from here?")
    +                                                end
    +                                        else
    +                                                UserMailer.sharing_notification(@project_group).deliver
    +                                                logger.debug("Email sent from there?")
    +                                        end
    +                                        flash[:notice] = message
    +                                        format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug }
    +                                        format.json { render json: @project_group, status: :created, location: @project_group }
    +                                else
    +                                        format.html { render action: "new" }
    +                                        format.json { render json: @project_group.errors, status: :unprocessable_entity }
    +                                end
    +                        else
    +                                flash[:notice] = "Please enter an email address"
    +                                format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug }
    +                                format.json { render json: @project_group, status: :created, location: @project_group }
    +                        end
    +                end                  
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +        
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/project_groups_controller.rb, line 82
    +def destroy
    +        @project_group = ProjectGroup.find(params[:id])
    +        if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then
    +                user = @project_group.user
    +                project = @project_group.project
    +                @project_group.destroy
    +                respond_to do |format|
    +                        flash[:notice] = 'Access removed'
    +                        UserMailer.project_access_removed_notification(user, project).deliver
    +                        format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug }
    +                        format.json { head :no_content }
    +                end
    +        else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/project_groups_controller.rb, line 52
    +def update
    +@project_group = ProjectGroup.find(params[:id])
    +access_level = params[:project_group][:access_level].to_i
    +        if access_level >= 3 then
    +                @project_group.project_administrator = true
    +        else
    +                @project_group.project_administrator = false
    +        end
    +        if access_level >= 2 then
    +                @project_group.project_editor = true
    +        else
    +                @project_group.project_editor = false
    +        end
    +if (user_signed_in?) && @project_group.project.administerable_by(current_user.id) then
    +                respond_to do |format|
    +                        if @project_group.update_attributes(params[:project_group])
    +                                flash[:notice] = 'Sharing details successfully updated.'
    +                                UserMailer.permissions_change_notification(@project_group).deliver
    +                                format.html { redirect_to :controller => 'projects', :action => 'share', :id => @project_group.project.slug }
    +                                format.json { head :no_content }
    +                        else
    +                                format.html { render action: "edit" }
    +                                format.json { render json: @project_group.errors, status: :unprocessable_entity }
    +                         end
    +                end
    +else
    +                render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ProjectPartner.html b/public/html/ProjectPartner.html new file mode 100644 index 0000000..07f619b --- /dev/null +++ b/public/html/ProjectPartner.html @@ -0,0 +1,279 @@ + + + + + + +class ProjectPartner - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectPartner

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Question.html b/public/html/Question.html new file mode 100644 index 0000000..a45775f --- /dev/null +++ b/public/html/Question.html @@ -0,0 +1,470 @@ + + + + + + +class Question - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Question

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + get_suggested_answer(org_id) + click to toggle source +
    + + +
    + +

    get suggested answer belonging to the currents user for this question

    + + + +
    +
    # File app/models/question.rb, line 99
    +def get_suggested_answer(org_id)
    +        suggested_answer = suggested_answers.find_by_organisation_id(org_id)
    +        return suggested_answer
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + guidance_for_question(question, org_admin) + click to toggle source +
    + + +
    + +

    guidance for question in the org admin

    + + + +
    +
    # File app/models/question.rb, line 69
    +def guidance_for_question(question, org_admin)
    +# pulls together guidance from various sources for question
    +
    +guidances = {}
    +theme_ids = question.theme_ids
    +
    +GuidanceGroup.where("organisation_id = ?", org_admin.id).each do |group|
    +    group.guidances.each do |g|
    +        g.themes.where("id IN (?)", theme_ids).each do |gg|
    +           guidances["#{group.name} guidance on #{gg.title}"] = g
    +        end
    +    end
    +end
    +
    +       # Guidance link to directly to a question
    +
    +question.guidances.each do |g_by_q|
    +    g_by_q.guidance_groups.each do |group|
    +        if group.organisation == org_admin
    +            guidances["#{group.name} guidance for this question"] = g_by_q
    +        end
    +    end
    +       end
    +
    +        return guidances
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + question_themes?() + click to toggle source +
    + + +
    + +

    def question_type?

    + +
    type_label = {}
    +if self.is_text_field?
    +  type_label = 'Text field'
    +elsif self.multiple_choice?
    +        type_label = 'Multiple choice'
    +else
    +        type_label = 'Text area'
    +end
    +return type_label
    + +

    end

    + + + +
    +
    # File app/models/question.rb, line 51
    +def question_themes?
    +        themes_label = {}
    +        i = 1
    +        themes_quest = self.themes
    +
    +        themes_quest.each do |tt|
    +                themes_label = tt.title
    +
    +                if themes_quest.count > i then
    +                        themes_label +=     ','
    +                        i +=1
    +                end
    +        end
    +
    +        return themes_label
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/question.rb, line 29
    +    def to_s
    +    "#{text}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/QuestionFormat.html b/public/html/QuestionFormat.html new file mode 100644 index 0000000..7d098d1 --- /dev/null +++ b/public/html/QuestionFormat.html @@ -0,0 +1,325 @@ + + + + + + +class QuestionFormat - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class QuestionFormat

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/question_format.rb, line 7
    + def to_s
    +  "#{title}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/README_rdoc.html b/public/html/README_rdoc.html new file mode 100644 index 0000000..1100184 --- /dev/null +++ b/public/html/README_rdoc.html @@ -0,0 +1,311 @@ + + + + + + +README - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    + +

    DMPonline v4

    + +

    DMPonline is the DCC's data management planning tool, available at dmponline.dcc.ac.uk

    + +

    Development of the DMPonline by the Digital Curation Centre has been funded +by JISC. JISC inspires UK colleges and universities in the innovative use +of digital technologies, helping to maintain the UK's position as a +global leader in education. www.jisc.ac.uk

    + +

    This is just the application code, the accompanying question data available +at dmponline.dcc.ac.uk is not +included.

    + +

    The tool has four main functions

    +
    1. +

      To help create and maintain different versions of Data Management Plans;

      +
    2. +

      To provide useful guidance on data management issues and how to meet +research funders' requirements;

      +
    3. +

      To export attractive and useful plans in a variety of formats;

      +
    4. +

      To allow collaborative work when creating Data Management Plans.

      +
    + +

    Documentation & Support

    +
    • +

      You can contact us by email, dmponline@dcc.ac.uk, but we can only provide +limited support for your installation

      +
    + +

    Bugs & Feature Requests

    + + +

    Prerequisites

    + +

    DMPonline is a Ruby on Rails application and you will need to have Ruby +2.0.0p247 or greater installed on your server and a MySQL server v5.0 or +greater.

    + +

    Further details on how to install Ruby on Rails applications are available +from the Ruby on Rails site, rubyonrails.org

    + +

    You may also find the following resources handy:

    + + + + +

    Copyright © 2013 Digital Curation Centre, University of Edinburgh.

    + +

    This program is free software: you can redistribute it and/or modify it +under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at your +option) any later version.

    + +

    This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License +for more details.

    + +

    You should have received a copy of the GNU Affero General Public License +along with this program. If not, see www.gnu.org/licenses.

    + +
    + + + + + diff --git a/public/html/RegistrationsController.html b/public/html/RegistrationsController.html new file mode 100644 index 0000000..c12611d --- /dev/null +++ b/public/html/RegistrationsController.html @@ -0,0 +1,506 @@ + + + + + + +class RegistrationsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class RegistrationsController

    + +
    + +

    app/controllers/registrations_controller.rb

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /resource

    + + + +
    +
    # File app/controllers/registrations_controller.rb, line 6
    +def create
    +      if sign_up_params[:accept_terms] != "1" then
    +        redirect_to after_sign_up_error_path_for(resource), alert: 'You must accept the terms and conditions to register.'
    +      else
    +              existing_user = User.find_by_email(sign_up_params[:email])
    +              if !existing_user.nil? then
    +                      if existing_user.dmponline3 && (existing_user.password == "" || existing_user.password.nil?) && existing_user.confirmed_at.nil? then
    +                              @user = existing_user
    +                              do_update(false, true)
    +                      else
    +                          redirect_to after_sign_up_error_path_for(resource), alert: 'That email address is already registered.'
    +                      end
    +              else
    +                      build_resource(sign_up_params)
    +                      if resource.save
    +                        if resource.active_for_authentication?
    +                              set_flash_message :notice, :signed_up if is_navigational_format?
    +                              sign_up(resource_name, resource)
    +                              respond_with resource, :location => after_sign_up_path_for(resource)
    +                        else
    +                              set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
    +                              expire_session_data_after_sign_in!
    +                              respond_with resource, :location => after_inactive_sign_up_path_for(resource)
    +                        end
    +                      else
    +                        clean_up_passwords resource
    +                        redirect_to after_sign_up_error_path_for(resource), alert: 'Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long.'
    +                      end
    +              end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/registrations_controller.rb, line 39
    +def update
    +       if user_signed_in? then
    +               @user = User.find(current_user.id)
    +
    +       do_update
    +   else
    +       render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
    +   end
    + end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + do_update(require_password = true, confirm = false) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/registrations_controller.rb, line 59
    +def do_update(require_password = true, confirm = false)
    +
    +        if require_password then
    +                successfully_updated = if needs_password?(@user, params)
    +    @user.update_with_password(params[:user])
    +    else
    +      # remove the virtual current_password attribute update_without_password
    +
    +      # doesn't know how to ignore it
    +
    +      params[:user].delete(:current_password)
    +      @user.update_without_password(params[:user])
    +    end
    +  else
    +      @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation])
    +      successfully_updated = @user.update_without_password(params[:user])
    +  end
    +
    +  #unlink shibboleth from user's details
    +
    +  if params[:unlink_flag] == 'true' then
    +    @user.update_attributes(:shibboleth_id => "")
    +  end
    +
    +  if successfully_updated
    +              if confirm then
    +                      @user.skip_confirmation!
    +                      @user.save!
    +              end
    +      set_flash_message :notice, :updated
    +      # Sign in the user bypassing validation in case his password changed
    +
    +      sign_in @user, :bypass => true
    +      
    +      if params[:unlink_flag] == 'true' then
    +          redirect_to({:controller => "registrations", :action => "edit"}, {:notice => "Details successfully updated."})
    +      else
    +          redirect_to({:controller => "projects", :action => "index"}, {:notice => "Details successfully updated."})
    +      end
    +
    +  else
    +    render "edit"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + needs_password?(user, params) + click to toggle source +
    + + +
    + +

    check if we need password to update user data ie if password or email was +changed extend this as needed

    + + + +
    +
    # File app/controllers/registrations_controller.rb, line 54
    +def needs_password?(user, params)
    +  user.email != params[:user][:email] ||
    +    params[:user][:password].present?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Role.html b/public/html/Role.html new file mode 100644 index 0000000..02d87ea --- /dev/null +++ b/public/html/Role.html @@ -0,0 +1,279 @@ + + + + + + +class Role - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Role

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Section.html b/public/html/Section.html new file mode 100644 index 0000000..2ad9bcb --- /dev/null +++ b/public/html/Section.html @@ -0,0 +1,325 @@ + + + + + + +class Section - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Section

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/section.rb, line 15
    +def to_s
    +  "#{title}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/SessionsController.html b/public/html/SessionsController.html new file mode 100644 index 0000000..163a22b --- /dev/null +++ b/public/html/SessionsController.html @@ -0,0 +1,375 @@ + + + + + + +class SessionsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class SessionsController

    + +
    + +

    app/controllers/sessions_controller.rb

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/sessions_controller.rb, line 4
    +def create
    +        existing_user = User.find_by_email(params[:user][:email])
    +
    +if !existing_user.nil? && existing_user.dmponline3 && (existing_user.password == "" || existing_user.password.nil?) && existing_user.confirmed_at.nil? then
    +                redirect_to :controller => :existing_users, :action => :index, :email => params[:user][:email]
    +        else
    +                #after authentication verify if session[:shibboleth] exists
    +
    +    if !params[:shibboleth_data].nil? then
    +        existing_user.update_attributes(:shibboleth_id => session[:shibboleth_data][:uid])
    +    end
    +    super
    +    
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/sessions_controller.rb, line 19
    +    def destroy
    +    current_user.plan_sections.each do |lock|
    +        lock.delete
    +        
    +    end
    +    super
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Settings.html b/public/html/Settings.html new file mode 100644 index 0000000..3cfcfa5 --- /dev/null +++ b/public/html/Settings.html @@ -0,0 +1,277 @@ + + + + + + +module Settings - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module Settings

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Settings/Dmptemplate.html b/public/html/Settings/Dmptemplate.html new file mode 100644 index 0000000..ed8991b --- /dev/null +++ b/public/html/Settings/Dmptemplate.html @@ -0,0 +1,312 @@ + + + + + + +class Settings::Dmptemplate - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Settings::Dmptemplate

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    DEFAULT_SETTINGS + +
    + + +
    VALID_ADMIN_FIELDS + +
    + + +
    VALID_FONT_FACES + +
    + + +
    VALID_FONT_SIZE_RANGE + +
    + + +
    VALID_MARGIN_RANGE + +
    + + +
    +
    + + + + + + +
    + +
    + + + + diff --git a/public/html/Settings/PlanList.html b/public/html/Settings/PlanList.html new file mode 100644 index 0000000..d213468 --- /dev/null +++ b/public/html/Settings/PlanList.html @@ -0,0 +1,297 @@ + + + + + + +class Settings::PlanList - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Settings::PlanList

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    ALL_COLUMNS + +
    + + +
    DEFAULT_COLUMNS + +

    TODO: can these be taken from somewhere else rather than hard-coded here?

    + + +
    +
    + + + + + + +
    + +
    + + + + diff --git a/public/html/Settings/PlansController.html b/public/html/Settings/PlansController.html new file mode 100644 index 0000000..25d458b --- /dev/null +++ b/public/html/Settings/PlansController.html @@ -0,0 +1,486 @@ + + + + + + +class Settings::PlansController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Settings::PlansController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/plans_controller.rb, line 6
    +def show
    +  respond_to do |format|
    +    format.html
    +    format.partial
    +    format.json { render json: settings_json }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/plans_controller.rb, line 14
    +def update
    +
    +  export_params = params[:export].try(:deep_symbolize_keys)
    +
    +  settings = plan.super_settings(:export).tap do |s|
    +    if params[:commit] == 'Reset'
    +      s.formatting = nil
    +      s.fields = nil
    +    else
    +      s.formatting = export_params[:formatting]
    +      s.fields = export_params[:fields]
    +      s.title  = export_params[:title]
    +    end
    +  end
    +
    +  if settings.save
    +    respond_to do |format|
    +      format.html { redirect_to(export_project_path(plan.project)) }
    +      format.json { render json: settings_json }
    +    end
    +  else
    +    settings.formatting = nil
    +    @export_settings = settings
    +    render(action: :show)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + get_settings() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/plans_controller.rb, line 43
    +def get_settings
    +  @export_settings = plan.settings(:export)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + plan() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/plans_controller.rb, line 51
    +def plan
    +  @plan ||= Plan.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + settings_json() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/plans_controller.rb, line 47
    +def settings_json
    +  @settings_json ||= { export: @export_settings }.to_json
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Settings/ProjectsController.html b/public/html/Settings/ProjectsController.html new file mode 100644 index 0000000..aa17b2f --- /dev/null +++ b/public/html/Settings/ProjectsController.html @@ -0,0 +1,445 @@ + + + + + + +class Settings::ProjectsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Settings::ProjectsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/projects_controller.rb, line 7
    +def show
    +  respond_to do |format|
    +    format.html
    +    format.json { render json: settings_json }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/projects_controller.rb, line 14
    +def update
    +  columns = (params[:columns] || {}).keys.map(&:intern)
    +
    +  if @settings.update_attributes(columns: columns)
    +    respond_to do |format|
    +      format.html { redirect_to(projects_path) }
    +      format.json { render json: settings_json }
    +    end
    +  else
    +    render(action: :show) # Expect #show to display errors etc
    +
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Private Instance Methods

    + + +
    + +
    + get_settings() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/projects_controller.rb, line 29
    +def get_settings
    +  @settings = current_user.settings(:plan_list)
    +  # :name column should always be present (displayed as a disabled checkbox)
    +
    +  # so it's not necessary to include it in the list here
    +
    +  @all_columns -= [:name]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + settings_json() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/settings/projects_controller.rb, line 36
    +def settings_json
    +  @settings_json ||= { selected_columns: @settings.columns, all_columns: @all_columns }.to_json
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Settings/SettingsController.html b/public/html/Settings/SettingsController.html new file mode 100644 index 0000000..6273362 --- /dev/null +++ b/public/html/Settings/SettingsController.html @@ -0,0 +1,279 @@ + + + + + + +class Settings::SettingsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Settings::SettingsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/SplashLog.html b/public/html/SplashLog.html new file mode 100644 index 0000000..41ac7d7 --- /dev/null +++ b/public/html/SplashLog.html @@ -0,0 +1,279 @@ + + + + + + +class SplashLog - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class SplashLog

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/SplashLogsController.html b/public/html/SplashLogsController.html new file mode 100644 index 0000000..b00abb8 --- /dev/null +++ b/public/html/SplashLogsController.html @@ -0,0 +1,337 @@ + + + + + + +class SplashLogsController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class SplashLogsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /answers POST /answers.json

    + + + +
    +
    # File app/controllers/splash_logs_controller.rb, line 5
    +def create
    +        @splash_log = SplashLog.new()
    +        @splash_log.destination = params[:destination]
    +        respond_to do |format|
    +                if @splash_log.save
    +                        cookies[:dmp_splash_seen] = {
    +                                value: 'splash_dialog_seen',
    +                                expires: 3.hours.from_now,
    +                        }
    +                        format.html { redirect_to params[:destination] }
    +                else
    +                        format.html { redirect_to home_url }
    +                end
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/StaticPagesController.html b/public/html/StaticPagesController.html new file mode 100644 index 0000000..65858ab --- /dev/null +++ b/public/html/StaticPagesController.html @@ -0,0 +1,392 @@ + + + + + + +class StaticPagesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class StaticPagesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + about_us() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/static_pages_controller.rb, line 3
    +def about_us
    +    dcc_news_feed_url = "http://www.dcc.ac.uk/news/dmponline-0/feed"
    +      @dcc_news_feed = Feedzirra::Feed.fetch_and_parse(dcc_news_feed_url)
    +      respond_to do |format|
    +          format.rss { redirect_to dcc_news_feed_url }
    +          format.html
    +      end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + contact_us() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/static_pages_controller.rb, line 12
    +def contact_us
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + roadmap() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/static_pages_controller.rb, line 15
    +def roadmap
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/SuggestedAnswer.html b/public/html/SuggestedAnswer.html new file mode 100644 index 0000000..707f287 --- /dev/null +++ b/public/html/SuggestedAnswer.html @@ -0,0 +1,325 @@ + + + + + + +class SuggestedAnswer - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class SuggestedAnswer

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/suggested_answer.rb, line 11
    +      def to_s
    +  "#{text}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Theme.html b/public/html/Theme.html new file mode 100644 index 0000000..5cb3a3a --- /dev/null +++ b/public/html/Theme.html @@ -0,0 +1,325 @@ + + + + + + +class Theme - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Theme

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/theme.rb, line 15
    +def to_s
    +      title
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/ThemesController.html b/public/html/ThemesController.html new file mode 100644 index 0000000..425e06a --- /dev/null +++ b/public/html/ThemesController.html @@ -0,0 +1,561 @@ + + + + + + +class ThemesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class ThemesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /themes POST /themes.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 42
    +def create
    +  @theme = Theme.new(params[:theme])
    +
    +  respond_to do |format|
    +    if @theme.save
    +      format.html { redirect_to @theme, notice: 'Theme was successfully created.' }
    +      format.json { render json: @theme, status: :created, location: @theme }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @theme.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /themes/1 DELETE /themes/1.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 74
    +def destroy
    +  @theme = Theme.find(params[:id])
    +  @theme.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to themes_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /themes/1/edit

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 36
    +def edit
    +  @theme = Theme.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /themes GET /themes.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 4
    +def index
    +  @themes = Theme.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @themes }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /themes/new GET /themes/new.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 26
    +def new
    +  @theme = Theme.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @theme }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /themes/1 GET /themes/1.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 15
    +def show
    +  @theme = Theme.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @theme }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /themes/1 PUT /themes/1.json

    + + + +
    +
    # File app/controllers/themes_controller.rb, line 58
    +def update
    +  @theme = Theme.find(params[:id])
    +
    +  respond_to do |format|
    +    if @theme.update_attributes(params[:theme])
    +      format.html { redirect_to @theme, notice: 'Theme was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @theme.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/User.html b/public/html/User.html new file mode 100644 index 0000000..a2e0c45 --- /dev/null +++ b/public/html/User.html @@ -0,0 +1,661 @@ + + + + + + +class User - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class User

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + current_organisation() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 98
    +def current_organisation
    +        if self.organisations.count > 0 then
    +                return self.organisations.last
    +        else
    +                return nil
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + filter(query) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 19
    +def filter(query)
    +  return self unless query.present?
    +
    +  t = self.arel_table
    +  q = "%#{query}%"
    +
    +  conditions = t[:title].matches(q)
    +
    +  columns = %(
    +    grant_number identifier description principal_investigator data_contact
    +  )
    +
    +  columns.each {|col| conditions = conditions.or(t[col].matches(q)) }
    +
    +  self.where(conditions)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can_super_admin?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 110
    +def can_super_admin?
    +        admin = roles.find_by_name("admin")
    +        return !admin.nil?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can_org_admin?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 115
    +def can_org_admin?
    +        org_admin = roles.find_by_name("org_admin")
    +        return !org_admin.nil?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + name(use_email = true) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 54
    +def name(use_email = true)
    +        if ((firstname.nil? && surname.nil?) || (firstname.strip == "" && surname.strip == "")) && use_email then
    +                return email
    +        else
    +                name = "#{firstname} #{surname}"
    +                return name.strip
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + org_type() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 120
    +def org_type
    +    org_type = organisation.organisation_type.name
    +            return org_type
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + organisation() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 90
    +def organisation
    +        if self.organisations.count > 0 then
    +                return self.organisations.first
    +        else
    +                return nil
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + organisation=(new_organisation) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 106
    +def organisation=(new_organisation)
    +        organisation_id = organisation.id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + organisation_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 82
    +def organisation_id
    +        if self.organisations.count > 0 then
    +                return self.organisations.first.id
    +        else
    +                return nil
    +        end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + organisation_id=(new_organisation_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 63
    +    def organisation_id=(new_organisation_id)
    +if !self.user_org_roles.pluck(:organisation_id).include?(new_organisation_id.to_i) then
    +            if self.user_org_roles.count != 1 then
    +                    new_user_org_role = UserOrgRole.new
    +                    new_user_org_role.organisation_id = new_organisation_id
    +                    new_user_org_role.user_role_type = UserRoleType.find_by_name("user");
    +                    self.user_org_roles << new_user_org_role
    +            else
    +                    user_org_role = self.user_org_roles.first
    +                    user_org_role.organisation_id = new_organisation_id
    +        user_org_role.save
    +                    org_admin_role = roles.find_by_name("org_admin")
    +                    unless org_admin_role.nil? then
    +                            roles.delete(org_admin_role)
    +                    end
    +            end
    +end
    +    end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UserMailer.html b/public/html/UserMailer.html new file mode 100644 index 0000000..9a51758 --- /dev/null +++ b/public/html/UserMailer.html @@ -0,0 +1,393 @@ + + + + + + +class UserMailer - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserMailer

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + permissions_change_notification(project_group) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/user_mailer.rb, line 9
    +def permissions_change_notification(project_group)
    +        @project_group = project_group
    +        mail(to: @project_group.user.email, subject: "DMP permissions changed")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_access_removed_notification(user, project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/user_mailer.rb, line 14
    +def project_access_removed_notification(user, project)
    +        @user = user
    +        @project = project
    +        mail(to: @user.email, subject: "DMP access removed")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + sharing_notification(project_group) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/user_mailer.rb, line 4
    +def sharing_notification(project_group)
    +        @project_group = project_group
    +        mail(to: @project_group.user.email, subject: "You have been given access to a Data Management Plan")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UserOrgRole.html b/public/html/UserOrgRole.html new file mode 100644 index 0000000..6ec474a --- /dev/null +++ b/public/html/UserOrgRole.html @@ -0,0 +1,279 @@ + + + + + + +class UserOrgRole - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserOrgRole

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/UserOrgRolesController.html b/public/html/UserOrgRolesController.html new file mode 100644 index 0000000..6612d49 --- /dev/null +++ b/public/html/UserOrgRolesController.html @@ -0,0 +1,561 @@ + + + + + + +class UserOrgRolesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserOrgRolesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /user_org_roles POST /user_org_roles.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 42
    +def create
    +  @user_org_role = UserOrgRole.new(params[:user_org_role])
    +
    +  respond_to do |format|
    +    if @user_org_role.save
    +      format.html { redirect_to @user_org_role, notice: 'User org role was successfully created.' }
    +      format.json { render json: @user_org_role, status: :created, location: @user_org_role }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @user_org_role.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /user_org_roles/1 DELETE /user_org_roles/1.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 74
    +def destroy
    +  @user_org_role = UserOrgRole.find(params[:id])
    +  @user_org_role.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to user_org_roles_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /user_org_roles/1/edit

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 36
    +def edit
    +  @user_org_role = UserOrgRole.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /user_org_roles GET /user_org_roles.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 4
    +def index
    +  @user_org_roles = UserOrgRole.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @user_org_roles }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /user_org_roles/new GET /user_org_roles/new.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 26
    +def new
    +  @user_org_role = UserOrgRole.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @user_org_role }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /user_org_roles/1 GET /user_org_roles/1.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 15
    +def show
    +  @user_org_role = UserOrgRole.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @user_org_role }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /user_org_roles/1 PUT /user_org_roles/1.json

    + + + +
    +
    # File app/controllers/user_org_roles_controller.rb, line 58
    +def update
    +  @user_org_role = UserOrgRole.find(params[:id])
    +
    +  respond_to do |format|
    +    if @user_org_role.update_attributes(params[:user_org_role])
    +      format.html { redirect_to @user_org_role, notice: 'User org role was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @user_org_role.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UserRoleType.html b/public/html/UserRoleType.html new file mode 100644 index 0000000..1808bff --- /dev/null +++ b/public/html/UserRoleType.html @@ -0,0 +1,279 @@ + + + + + + +class UserRoleType - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserRoleType

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/UserRoleTypesController.html b/public/html/UserRoleTypesController.html new file mode 100644 index 0000000..7ee343f --- /dev/null +++ b/public/html/UserRoleTypesController.html @@ -0,0 +1,561 @@ + + + + + + +class UserRoleTypesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserRoleTypesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /user_role_types POST /user_role_types.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 42
    +def create
    +  @user_role_type = UserRoleType.new(params[:user_role_type])
    +
    +  respond_to do |format|
    +    if @user_role_type.save
    +      format.html { redirect_to @user_role_type, notice: 'User role type was successfully created.' }
    +      format.json { render json: @user_role_type, status: :created, location: @user_role_type }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @user_role_type.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /user_role_types/1 DELETE /user_role_types/1.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 74
    +def destroy
    +  @user_role_type = UserRoleType.find(params[:id])
    +  @user_role_type.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to user_role_types_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /user_role_types/1/edit

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 36
    +def edit
    +  @user_role_type = UserRoleType.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /user_role_types GET /user_role_types.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 4
    +def index
    +  @user_role_types = UserRoleType.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @user_role_types }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /user_role_types/new GET /user_role_types/new.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 26
    +def new
    +  @user_role_type = UserRoleType.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @user_role_type }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /user_role_types/1 GET /user_role_types/1.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 15
    +def show
    +  @user_role_type = UserRoleType.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @user_role_type }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /user_role_types/1 PUT /user_role_types/1.json

    + + + +
    +
    # File app/controllers/user_role_types_controller.rb, line 58
    +def update
    +  @user_role_type = UserRoleType.find(params[:id])
    +
    +  respond_to do |format|
    +    if @user_role_type.update_attributes(params[:user_role_type])
    +      format.html { redirect_to @user_role_type, notice: 'User role type was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @user_role_type.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UserStatus.html b/public/html/UserStatus.html new file mode 100644 index 0000000..ece7b89 --- /dev/null +++ b/public/html/UserStatus.html @@ -0,0 +1,279 @@ + + + + + + +class UserStatus - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserStatus

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/UserStatusesController.html b/public/html/UserStatusesController.html new file mode 100644 index 0000000..e74b843 --- /dev/null +++ b/public/html/UserStatusesController.html @@ -0,0 +1,561 @@ + + + + + + +class UserStatusesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserStatusesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /user_statuses POST /user_statuses.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 42
    +def create
    +  @user_status = UserStatus.new(params[:user_status])
    +
    +  respond_to do |format|
    +    if @user_status.save
    +      format.html { redirect_to @user_status, notice: 'User status was successfully created.' }
    +      format.json { render json: @user_status, status: :created, location: @user_status }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @user_status.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /user_statuses/1 DELETE /user_statuses/1.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 74
    +def destroy
    +  @user_status = UserStatus.find(params[:id])
    +  @user_status.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to user_statuses_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /user_statuses/1/edit

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 36
    +def edit
    +  @user_status = UserStatus.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /user_statuses GET /user_statuses.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 4
    +def index
    +  @user_statuses = UserStatus.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @user_statuses }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /user_statuses/new GET /user_statuses/new.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 26
    +def new
    +  @user_status = UserStatus.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @user_status }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /user_statuses/1 GET /user_statuses/1.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 15
    +def show
    +  @user_status = UserStatus.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @user_status }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /user_statuses/1 PUT /user_statuses/1.json

    + + + +
    +
    # File app/controllers/user_statuses_controller.rb, line 58
    +def update
    +  @user_status = UserStatus.find(params[:id])
    +
    +  respond_to do |format|
    +    if @user_status.update_attributes(params[:user_status])
    +      format.html { redirect_to @user_status, notice: 'User status was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @user_status.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UserType.html b/public/html/UserType.html new file mode 100644 index 0000000..f37778b --- /dev/null +++ b/public/html/UserType.html @@ -0,0 +1,279 @@ + + + + + + +class UserType - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserType

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/UserTypesController.html b/public/html/UserTypesController.html new file mode 100644 index 0000000..7a53fd5 --- /dev/null +++ b/public/html/UserTypesController.html @@ -0,0 +1,561 @@ + + + + + + +class UserTypesController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UserTypesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /user_types POST /user_types.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 42
    +def create
    +  @user_type = UserType.new(params[:user_type])
    +
    +  respond_to do |format|
    +    if @user_type.save
    +      format.html { redirect_to @user_type, notice: 'User type was successfully created.' }
    +      format.json { render json: @user_type, status: :created, location: @user_type }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @user_type.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /user_types/1 DELETE /user_types/1.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 74
    +def destroy
    +  @user_type = UserType.find(params[:id])
    +  @user_type.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to user_types_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /user_types/1/edit

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 36
    +def edit
    +  @user_type = UserType.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + +

    GET /user_types GET /user_types.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 4
    +def index
    +  @user_types = UserType.all
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +
    +    format.json { render json: @user_types }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /user_types/new GET /user_types/new.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 26
    +def new
    +  @user_type = UserType.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @user_type }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /user_types/1 GET /user_types/1.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 15
    +def show
    +  @user_type = UserType.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @user_type }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /user_types/1 PUT /user_types/1.json

    + + + +
    +
    # File app/controllers/user_types_controller.rb, line 58
    +def update
    +  @user_type = UserType.find(params[:id])
    +
    +  respond_to do |format|
    +    if @user_type.update_attributes(params[:user_type])
    +      format.html { redirect_to @user_type, notice: 'User type was successfully updated.' }
    +      format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @user_type.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Users.html b/public/html/Users.html new file mode 100644 index 0000000..f059ad1 --- /dev/null +++ b/public/html/Users.html @@ -0,0 +1,272 @@ + + + + + + +module Users - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    module Users

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/public/html/Users/OmniauthCallbacksController.html b/public/html/Users/OmniauthCallbacksController.html new file mode 100644 index 0000000..ee178a1 --- /dev/null +++ b/public/html/Users/OmniauthCallbacksController.html @@ -0,0 +1,374 @@ + + + + + + +class Users::OmniauthCallbacksController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Users::OmniauthCallbacksController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + shibboleth() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/users/omniauth_callback_controller.rb, line 3
    +def shibboleth
    +  if user_signed_in? && current_user.shibboleth_id.present? && current_user.shibboleth_id.length > 0 then
    +    flash[:warning] = I18n.t('devise.failure.already_authenticated')
    +    redirect_to root_path
    +  else
    +    auth = request.env['omniauth.auth'] || {}
    +    eppn = auth['extra']['raw_info']['eppn']
    +    uid = nil
    +    if !eppn.blank? then
    +      uid = eppn
    +    elsif !auth['uid'].blank? then
    +      uid = auth['uid']
    +    elsif !auth['extra']['raw_info']['targeted-id'].blank? then
    +      uid = auth['extra']['raw_info']['targeted-id']
    +    end
    +
    +    if !uid.nil? && !uid.blank? then
    +                              s_user = User.where(shibboleth_id: uid).first
    +                              # Take out previous record if was not confirmed.
    +
    +                              if !s_user.nil? && s_user.confirmed_at.nil? then
    +                                      sign_out s_user
    +                                      User.delete(s_user.id)
    +                                      s_user = nil
    +                              end
    +
    +                              # Stops Shibboleth ID being blocked if email incorrectly entered.
    +
    +                              if !s_user.nil? && s_user.try(:persisted?) then
    +                                      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', :kind => 'Shibboleth')
    +                                      sign_in s_user
    +                  redirect_to root_path
    +                              else
    +                                      if user_signed_in? then
    +                                              current_user.update_attribute('shibboleth_id', uid)
    +                                              user_id = current_user.id
    +                                              sign_out current_user
    +                                              session.delete(:shibboleth_data)
    +                                              s_user = User.find(user_id)
    +                                              sign_in s_user
    +                      redirect_to edit_user_registration_path
    +                                      else
    +                                              session[:shibboleth_data] = request.env['omniauth.auth']
    +                                              session[:shibboleth_data][:uid] = uid
    +                                              redirect_to new_user_registration_url(:nosplash => 'true')
    +                                      end
    +                              end
    +    else
    +      redirect_to root_path
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/UsersController.html b/public/html/UsersController.html new file mode 100644 index 0000000..6ac90b1 --- /dev/null +++ b/public/html/UsersController.html @@ -0,0 +1,523 @@ + + + + + + +class UsersController - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class UsersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + +

    POST /users POST /users.json

    + + + +
    +
    # File app/controllers/users_controller.rb, line 31
    +def create
    +  @user = User.new(params[:user])
    +
    +  respond_to do |format|
    +    if @user.save
    +      format.html { redirect_to @user, notice: 'User was successfully created.' }
    +      format.json { render json: @user, status: :created, location: @user }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @user.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + +

    DELETE /users/1 DELETE /users/1.json

    + + + +
    +
    # File app/controllers/users_controller.rb, line 66
    +def destroy
    +  @user = User.find(params[:id])
    +  @user.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to users_url }
    +    format.json { head :no_content }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + +

    GET /users/1/edit

    + + + +
    +
    # File app/controllers/users_controller.rb, line 25
    +def edit
    +  @user = User.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + +

    GET /users/new GET /users/new.json

    + + + +
    +
    # File app/controllers/users_controller.rb, line 15
    +def new
    +  @user = User.new
    +
    +  respond_to do |format|
    +    format.html # new.html.erb
    +
    +    format.json { render json: @user }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + +

    GET /users/1 GET /users/1.json

    + + + +
    +
    # File app/controllers/users_controller.rb, line 4
    +def show
    +  @user = User.find(params[:id])
    +
    +  respond_to do |format|
    +    format.html # show.html.erb
    +
    +    format.json { render json: @user }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + +

    PUT /users/1 PUT /users/1.json

    + + + +
    +
    # File app/controllers/users_controller.rb, line 47
    +def update
    +  @user = User.find(params[:id])
    +
    +  respond_to do |format|
    +    if @user.update_attributes(params[:user])
    +      format.html { redirect_to({:controller=> "projects", :action => "new"}, {:notice => 'Project was successfully created.'}) }
    +                              format.json { head :no_content }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @user.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/Version.html b/public/html/Version.html new file mode 100644 index 0000000..bfa9737 --- /dev/null +++ b/public/html/Version.html @@ -0,0 +1,357 @@ + + + + + + +class Version - DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    +

    class Version

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + global_sections() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/version.rb, line 22
    +def global_sections
    +      sections.find_all_by_organisation_id(phase.dmptemplate.organisation_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_s() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/version.rb, line 16
    +def to_s
    +      "#{title}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/public/html/created.rid b/public/html/created.rid new file mode 100644 index 0000000..1ff390d --- /dev/null +++ b/public/html/created.rid @@ -0,0 +1,115 @@ +Mon, 09 Nov 2015 14:55:18 +0000 +README.rdoc Tue, 28 Jul 2015 13:51:53 +0100 +app/admin/dashboard.rb Wed, 18 Mar 2015 14:45:56 +0000 +app/admin/dmptemplate.rb Wed, 18 Mar 2015 11:10:34 +0000 +app/admin/guidance.rb Fri, 02 Oct 2015 10:07:14 +0100 +app/admin/guidance_group.rb Mon, 09 Nov 2015 14:30:03 +0000 +app/admin/option.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/organisation.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/organisation_type.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/phase.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/project.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/project_group.rb Wed, 11 Mar 2015 16:23:43 +0000 +app/admin/question.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/question_format.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/role.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/section.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/suggested_answer.rb Wed, 11 Mar 2015 16:23:43 +0000 +app/admin/theme.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/user.rb Wed, 28 Oct 2015 11:08:46 +0000 +app/admin/user_org_role.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/user_role_type.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/user_status.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/user_type.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/admin/version.rb Fri, 02 Oct 2015 10:09:28 +0100 +app/controllers/answers_controller.rb Thu, 16 Apr 2015 10:05:23 +0100 +app/controllers/application_controller.rb Fri, 09 Oct 2015 16:05:22 +0100 +app/controllers/comments_controller.rb Tue, 19 May 2015 16:11:58 +0100 +app/controllers/confirmations_controller.rb Wed, 09 Oct 2013 11:00:51 +0100 +app/controllers/contacts_controller.rb Mon, 27 Jul 2015 16:51:02 +0100 +app/controllers/dmptemplates_controller.rb Mon, 10 Aug 2015 12:44:35 +0100 +app/controllers/existing_users_controller.rb Tue, 26 Nov 2013 17:15:46 +0000 +app/controllers/guidance_groups_controller.rb Sun, 09 Aug 2015 14:54:18 +0100 +app/controllers/guidances_controller.rb Sun, 05 Jul 2015 22:48:47 +0100 +app/controllers/home_controller.rb Thu, 26 Sep 2013 17:04:25 +0100 +app/controllers/organisation_users_controller.rb Mon, 27 Jan 2014 15:09:50 +0000 +app/controllers/organisations_controller.rb Sun, 09 Aug 2015 14:52:46 +0100 +app/controllers/passwords_controller.rb Wed, 09 Oct 2013 11:00:51 +0100 +app/controllers/plans_controller.rb Mon, 26 Oct 2015 18:34:42 +0000 +app/controllers/project_groups_controller.rb Mon, 09 Dec 2013 10:57:33 +0000 +app/controllers/projects_controller.rb Sun, 05 Jul 2015 19:32:06 +0100 +app/controllers/registrations_controller.rb Wed, 23 Jul 2014 11:56:43 +0100 +app/controllers/sessions_controller.rb Mon, 24 Aug 2015 13:24:15 +0100 +app/controllers/settings.rb Fri, 02 Oct 2015 12:12:20 +0100 +app/controllers/settings/plans_controller.rb Wed, 09 Jul 2014 16:26:32 +0100 +app/controllers/settings/projects_controller.rb Mon, 07 Jul 2014 11:30:19 +0100 +app/controllers/splash_logs_controller.rb Wed, 27 Nov 2013 15:15:11 +0000 +app/controllers/static_pages_controller.rb Thu, 21 May 2015 16:13:16 +0100 +app/controllers/themes_controller.rb Tue, 24 Sep 2013 15:31:14 +0100 +app/controllers/user_org_roles_controller.rb Tue, 24 Sep 2013 15:31:14 +0100 +app/controllers/user_role_types_controller.rb Tue, 24 Sep 2013 15:31:14 +0100 +app/controllers/user_statuses_controller.rb Tue, 24 Sep 2013 15:31:14 +0100 +app/controllers/user_types_controller.rb Tue, 24 Sep 2013 15:31:14 +0100 +app/controllers/users/omniauth_callback_controller.rb Mon, 27 Jul 2015 12:31:00 +0100 +app/controllers/users/omniauth_shibboleth_request_controller.rb Tue, 15 Apr 2014 13:55:12 +0100 +app/controllers/users_controller.rb Tue, 12 May 2015 18:45:56 +0100 +app/helpers/application_helper.rb Mon, 10 Aug 2015 02:17:40 +0100 +app/helpers/plans_helper.rb Mon, 07 Jul 2014 11:30:19 +0100 +app/mailers/user_mailer.rb Tue, 26 Nov 2013 14:18:11 +0000 +app/models/ability.rb Tue, 06 Oct 2015 19:51:17 +0100 +app/models/answer.rb Tue, 06 Oct 2015 19:49:57 +0100 +app/models/comment.rb Tue, 06 Oct 2015 19:49:53 +0100 +app/models/dmptemplate.rb Tue, 06 Oct 2015 19:49:56 +0100 +app/models/exported_plan.rb Wed, 21 Oct 2015 14:41:40 +0100 +app/models/file_type.rb Tue, 06 Oct 2015 19:51:17 +0100 +app/models/file_upload.rb Tue, 06 Oct 2015 19:51:18 +0100 +app/models/guidance.rb Tue, 06 Oct 2015 19:49:51 +0100 +app/models/guidance_group.rb Tue, 06 Oct 2015 19:49:52 +0100 +app/models/option.rb Tue, 06 Oct 2015 19:49:56 +0100 +app/models/option_warning.rb Tue, 06 Oct 2015 19:49:57 +0100 +app/models/organisation.rb Tue, 06 Oct 2015 19:49:55 +0100 +app/models/organisation_type.rb Tue, 06 Oct 2015 19:51:18 +0100 +app/models/phase.rb Tue, 06 Oct 2015 19:49:51 +0100 +app/models/plan.rb Tue, 06 Oct 2015 19:49:56 +0100 +app/models/plan_section.rb Tue, 06 Oct 2015 19:51:19 +0100 +app/models/project.rb Tue, 06 Oct 2015 19:49:52 +0100 +app/models/project_group.rb Tue, 06 Oct 2015 19:51:19 +0100 +app/models/project_partner.rb Tue, 06 Oct 2015 19:51:16 +0100 +app/models/question.rb Tue, 06 Oct 2015 19:49:55 +0100 +app/models/question_format.rb Tue, 06 Oct 2015 19:51:20 +0100 +app/models/role.rb Tue, 06 Oct 2015 19:49:53 +0100 +app/models/section.rb Tue, 06 Oct 2015 19:51:20 +0100 +app/models/settings/dmptemplate.rb Tue, 06 Oct 2015 19:51:24 +0100 +app/models/settings/plan_list.rb Tue, 06 Oct 2015 19:51:25 +0100 +app/models/splash_log.rb Tue, 06 Oct 2015 19:51:20 +0100 +app/models/suggested_answer.rb Tue, 06 Oct 2015 19:51:21 +0100 +app/models/theme.rb Tue, 06 Oct 2015 19:51:21 +0100 +app/models/user.rb Tue, 06 Oct 2015 19:49:54 +0100 +app/models/user_org_role.rb Tue, 06 Oct 2015 19:51:22 +0100 +app/models/user_role_type.rb Tue, 06 Oct 2015 19:51:22 +0100 +app/models/user_status.rb Tue, 06 Oct 2015 19:51:23 +0100 +app/models/user_type.rb Tue, 06 Oct 2015 19:51:23 +0100 +app/models/version.rb Tue, 06 Oct 2015 19:51:24 +0100 +lib/active_admin_views_pages_base.rb Wed, 20 Nov 2013 16:27:04 +0000 +lib/custom_failure.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/application.rb Tue, 06 Oct 2015 15:02:51 +0100 +config/boot.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/environment.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/environments/development.rb Mon, 14 Jul 2014 15:43:22 +0100 +config/environments/production.rb Mon, 14 Jul 2014 15:43:22 +0100 +config/environments/test.rb Tue, 28 Jan 2014 12:43:49 +0000 +config/initializers/active_admin.rb Mon, 12 Oct 2015 16:20:30 +0100 +config/initializers/backtrace_silencers.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/contact_us.rb Mon, 14 Jul 2014 15:43:22 +0100 +config/initializers/devise.rb Fri, 02 Oct 2015 10:16:28 +0100 +config/initializers/formtastic.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/inflections.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/locale.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/mime_types.rb Mon, 14 Jul 2014 15:43:22 +0100 +config/initializers/omniauth.rb Mon, 07 Jul 2014 11:30:12 +0100 +config/initializers/recaptcha.rb Wed, 16 Jul 2014 16:29:56 +0100 +config/initializers/rolify.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/secret_token.rb Mon, 14 Jul 2014 15:43:22 +0100 +config/initializers/session_store.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/initializers/wrap_parameters.rb Tue, 24 Sep 2013 15:31:14 +0100 +config/routes.rb Thu, 21 May 2015 15:42:52 +0100 diff --git a/public/html/images/add.png b/public/html/images/add.png new file mode 100644 index 0000000..6332fef --- /dev/null +++ b/public/html/images/add.png Binary files differ diff --git a/public/html/images/brick.png b/public/html/images/brick.png new file mode 100644 index 0000000..7851cf3 --- /dev/null +++ b/public/html/images/brick.png Binary files differ diff --git a/public/html/images/brick_link.png b/public/html/images/brick_link.png new file mode 100644 index 0000000..9ebf013 --- /dev/null +++ b/public/html/images/brick_link.png Binary files differ diff --git a/public/html/images/bug.png b/public/html/images/bug.png new file mode 100644 index 0000000..2d5fb90 --- /dev/null +++ b/public/html/images/bug.png Binary files differ diff --git a/public/html/images/bullet_black.png b/public/html/images/bullet_black.png new file mode 100644 index 0000000..5761970 --- /dev/null +++ b/public/html/images/bullet_black.png Binary files differ diff --git a/public/html/images/bullet_toggle_minus.png b/public/html/images/bullet_toggle_minus.png new file mode 100644 index 0000000..b47ce55 --- /dev/null +++ b/public/html/images/bullet_toggle_minus.png Binary files differ diff --git a/public/html/images/bullet_toggle_plus.png b/public/html/images/bullet_toggle_plus.png new file mode 100644 index 0000000..9ab4a89 --- /dev/null +++ b/public/html/images/bullet_toggle_plus.png Binary files differ diff --git a/public/html/images/date.png b/public/html/images/date.png new file mode 100644 index 0000000..783c833 --- /dev/null +++ b/public/html/images/date.png Binary files differ diff --git a/public/html/images/delete.png b/public/html/images/delete.png new file mode 100644 index 0000000..08f2493 --- /dev/null +++ b/public/html/images/delete.png Binary files differ diff --git a/public/html/images/find.png b/public/html/images/find.png new file mode 100644 index 0000000..1547479 --- /dev/null +++ b/public/html/images/find.png Binary files differ diff --git a/public/html/images/loadingAnimation.gif b/public/html/images/loadingAnimation.gif new file mode 100644 index 0000000..82290f4 --- /dev/null +++ b/public/html/images/loadingAnimation.gif Binary files differ diff --git a/public/html/images/macFFBgHack.png b/public/html/images/macFFBgHack.png new file mode 100644 index 0000000..c6473b3 --- /dev/null +++ b/public/html/images/macFFBgHack.png Binary files differ diff --git a/public/html/images/package.png b/public/html/images/package.png new file mode 100644 index 0000000..da3c2a2 --- /dev/null +++ b/public/html/images/package.png Binary files differ diff --git a/public/html/images/page_green.png b/public/html/images/page_green.png new file mode 100644 index 0000000..de8e003 --- /dev/null +++ b/public/html/images/page_green.png Binary files differ diff --git a/public/html/images/page_white_text.png b/public/html/images/page_white_text.png new file mode 100644 index 0000000..813f712 --- /dev/null +++ b/public/html/images/page_white_text.png Binary files differ diff --git a/public/html/images/page_white_width.png b/public/html/images/page_white_width.png new file mode 100644 index 0000000..1eb8809 --- /dev/null +++ b/public/html/images/page_white_width.png Binary files differ diff --git a/public/html/images/plugin.png b/public/html/images/plugin.png new file mode 100644 index 0000000..6187b15 --- /dev/null +++ b/public/html/images/plugin.png Binary files differ diff --git a/public/html/images/ruby.png b/public/html/images/ruby.png new file mode 100644 index 0000000..f763a16 --- /dev/null +++ b/public/html/images/ruby.png Binary files differ diff --git a/public/html/images/tag_blue.png b/public/html/images/tag_blue.png new file mode 100644 index 0000000..3f02b5f --- /dev/null +++ b/public/html/images/tag_blue.png Binary files differ diff --git a/public/html/images/tag_green.png b/public/html/images/tag_green.png new file mode 100644 index 0000000..83ec984 --- /dev/null +++ b/public/html/images/tag_green.png Binary files differ diff --git a/public/html/images/transparent.png b/public/html/images/transparent.png new file mode 100644 index 0000000..d665e17 --- /dev/null +++ b/public/html/images/transparent.png Binary files differ diff --git a/public/html/images/wrench.png b/public/html/images/wrench.png new file mode 100644 index 0000000..5c8213f --- /dev/null +++ b/public/html/images/wrench.png Binary files differ diff --git a/public/html/images/wrench_orange.png b/public/html/images/wrench_orange.png new file mode 100644 index 0000000..565a933 --- /dev/null +++ b/public/html/images/wrench_orange.png Binary files differ diff --git a/public/html/images/zoom.png b/public/html/images/zoom.png new file mode 100644 index 0000000..908612e --- /dev/null +++ b/public/html/images/zoom.png Binary files differ diff --git a/public/html/index.html b/public/html/index.html new file mode 100644 index 0000000..d4524bb --- /dev/null +++ b/public/html/index.html @@ -0,0 +1,310 @@ + + + + + + +DMPonline4 Documentation + + + + + + + + + + + + + + + + +
    + +

    DMPonline v4

    + +

    DMPonline is the DCC's data management planning tool, available at dmponline.dcc.ac.uk

    + +

    Development of the DMPonline by the Digital Curation Centre has been funded +by JISC. JISC inspires UK colleges and universities in the innovative use +of digital technologies, helping to maintain the UK's position as a +global leader in education. www.jisc.ac.uk

    + +

    This is just the application code, the accompanying question data available +at dmponline.dcc.ac.uk is not +included.

    + +

    The tool has four main functions

    +
    1. +

      To help create and maintain different versions of Data Management Plans;

      +
    2. +

      To provide useful guidance on data management issues and how to meet +research funders' requirements;

      +
    3. +

      To export attractive and useful plans in a variety of formats;

      +
    4. +

      To allow collaborative work when creating Data Management Plans.

      +
    + +

    Documentation & Support

    +
    • +

      You can contact us by email, dmponline@dcc.ac.uk, but we can only provide +limited support for your installation

      +
    + +

    Bugs & Feature Requests

    + + +

    Prerequisites

    + +

    DMPonline is a Ruby on Rails application and you will need to have Ruby +2.0.0p247 or greater installed on your server and a MySQL server v5.0 or +greater.

    + +

    Further details on how to install Ruby on Rails applications are available +from the Ruby on Rails site, rubyonrails.org

    + +

    You may also find the following resources handy:

    + + + + +

    Copyright © 2013 Digital Curation Centre, University of Edinburgh.

    + +

    This program is free software: you can redistribute it and/or modify it +under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at your +option) any later version.

    + +

    This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License +for more details.

    + +

    You should have received a copy of the GNU Affero General Public License +along with this program. If not, see www.gnu.org/licenses.

    + +
    + + + + diff --git a/public/html/js/darkfish.js b/public/html/js/darkfish.js new file mode 100644 index 0000000..92d8280 --- /dev/null +++ b/public/html/js/darkfish.js @@ -0,0 +1,155 @@ +/** + * + * Darkfish Page Functions + * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* Provide console simulation for firebug-less environments */ +if (!("console" in window) || !("firebug" in console)) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +}; + + +/** + * Unwrap the first element that matches the given @expr@ from the targets and return them. + */ +$.fn.unwrap = function( expr ) { + return this.each( function() { + $(this).parents( expr ).eq( 0 ).after( this ).remove(); + }); +}; + + +function showSource( e ) { + var target = e.target; + var codeSections = $(target). + parents('.method-detail'). + find('.method-source-code'); + + $(target). + parents('.method-detail'). + find('.method-source-code'). + slideToggle(); +}; + +function hookSourceViews() { + $('.method-heading').click( showSource ); +}; + +function toggleDebuggingSection() { + $('.debugging-section').slideToggle(); +}; + +function hookDebuggingToggle() { + $('#debugging-toggle img').click( toggleDebuggingSection ); +}; + +function hookTableOfContentsToggle() { + $('.indexpage li .toc-toggle').each( function() { + $(this).click( function() { + $(this).toggleClass('open'); + }); + + var section = $(this).next(); + + $(this).click( function() { + section.slideToggle(); + }); + }); +} + +function hookSearch() { + var input = $('#search-field').eq(0); + var result = $('#search-results').eq(0); + $(result).show(); + + var search_section = $('#search-section').get(0); + $(search_section).show(); + + var search = new Search(search_data, input, result); + + search.renderItem = function(result) { + var li = document.createElement('li'); + var html = ''; + + // TODO add relative path to + + + + + + + + + + +

    Table of Contents - DMPonline4 Documentation

    + +

    Pages

    + + +

    Classes/Modules

    + + +

    Methods

    + + + + + diff --git a/public/i18n.js b/public/i18n.js new file mode 100644 index 0000000..9797f5b --- /dev/null +++ b/public/i18n.js @@ -0,0 +1,934 @@ +// I18n.js +// ======= +// +// This small library provides the Rails I18n API on the Javascript. +// You don't actually have to use Rails (or even Ruby) to use I18n.js. +// Just make sure you export all translations in an object like this: +// +// I18n.translations.en = { +// hello: "Hello World" +// }; +// +// See tests for specific formatting like numbers and dates. +// + +;(function(factory) { + if (typeof module !== 'undefined' && module.exports) { + // Node/CommonJS + module.exports = factory(this); + } else if (typeof define === 'function' && define.amd) { + // AMD + var global=this; + define('i18n', function(){ return factory(global);}); + } else { + // Browser globals + this.I18n = factory(this); + } +}(function(global) { + "use strict"; + + // Use previously defined object if exists in current scope + var I18n = global && global.I18n || {}; + + // Just cache the Array#slice function. + var slice = Array.prototype.slice; + + // Apply number padding. + var padding = function(number) { + return ("0" + number.toString()).substr(-2); + }; + + // Improved toFixed number rounding function with support for unprecise floating points + // JavaScript's standard toFixed function does not round certain numbers correctly (for example 0.105 with precision 2). + var toFixed = function(number, precision) { + return decimalAdjust('round', number, -precision).toFixed(precision); + }; + + // Is a given variable an object? + // Borrowed from Underscore.js + var isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Is a given value an array? + // Borrowed from Underscore.js + var isArray = function(obj) { + if (Array.isArray) { + return Array.isArray(obj); + }; + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + + var decimalAdjust = function(type, value, exp) { + // If the exp is undefined or zero... + if (typeof exp === 'undefined' || +exp === 0) { + return Math[type](value); + } + value = +value; + exp = +exp; + // If the value is not a number or the exp is not an integer... + if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { + return NaN; + } + // Shift + value = value.toString().split('e'); + value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); + // Shift back + value = value.toString().split('e'); + return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); + } + + // Set default days/months translations. + var DATE = { + day_names: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] + , abbr_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] + , month_names: [null, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] + , abbr_month_names: [null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + , meridian: ["AM", "PM"] + }; + + // Set default number format. + var NUMBER_FORMAT = { + precision: 3 + , separator: "." + , delimiter: "," + , strip_insignificant_zeros: false + }; + + // Set default currency format. + var CURRENCY_FORMAT = { + unit: "$" + , precision: 2 + , format: "%u%n" + , sign_first: true + , delimiter: "," + , separator: "." + }; + + // Set default percentage format. + var PERCENTAGE_FORMAT = { + unit: "%" + , precision: 3 + , format: "%n%u" + , separator: "." + , delimiter: "" + }; + + // Set default size units. + var SIZE_UNITS = [null, "kb", "mb", "gb", "tb"]; + + // Other default options + var DEFAULT_OPTIONS = { + // Set default locale. This locale will be used when fallback is enabled and + // the translation doesn't exist in a particular locale. + defaultLocale: "en" + // Set the current locale to `en`. + , locale: "en" + // Set the translation key separator. + , defaultSeparator: "." + // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`. + , placeholder: /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm + // Set if engine should fallback to the default locale when a translation + // is missing. + , fallbacks: false + // Set the default translation object. + , translations: {} + // Set missing translation behavior. 'message' will display a message + // that the translation is missing, 'guess' will try to guess the string + , missingBehaviour: 'message' + // if you use missingBehaviour with 'message', but want to know that the + // string is actually missing for testing purposes, you can prefix the + // guessed string by setting the value here. By default, no prefix! + , missingTranslationPrefix: '' + }; + + I18n.reset = function() { + // Set default locale. This locale will be used when fallback is enabled and + // the translation doesn't exist in a particular locale. + this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; + + // Set the current locale to `en`. + this.locale = DEFAULT_OPTIONS.locale; + + // Set the translation key separator. + this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator; + + // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`. + this.placeholder = DEFAULT_OPTIONS.placeholder; + + // Set if engine should fallback to the default locale when a translation + // is missing. + this.fallbacks = DEFAULT_OPTIONS.fallbacks; + + // Set the default translation object. + this.translations = DEFAULT_OPTIONS.translations; + + // Set the default missing behaviour + this.missingBehaviour = DEFAULT_OPTIONS.missingBehaviour; + + // Set the default missing string prefix for guess behaviour + this.missingTranslationPrefix = DEFAULT_OPTIONS.missingTranslationPrefix; + + }; + + // Much like `reset`, but only assign options if not already assigned + I18n.initializeOptions = function() { + if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null) + this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; + + if (typeof(this.locale) === "undefined" && this.locale !== null) + this.locale = DEFAULT_OPTIONS.locale; + + if (typeof(this.defaultSeparator) === "undefined" && this.defaultSeparator !== null) + this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator; + + if (typeof(this.placeholder) === "undefined" && this.placeholder !== null) + this.placeholder = DEFAULT_OPTIONS.placeholder; + + if (typeof(this.fallbacks) === "undefined" && this.fallbacks !== null) + this.fallbacks = DEFAULT_OPTIONS.fallbacks; + + if (typeof(this.translations) === "undefined" && this.translations !== null) + this.translations = DEFAULT_OPTIONS.translations; + }; + I18n.initializeOptions(); + + // Return a list of all locales that must be tried before returning the + // missing translation message. By default, this will consider the inline option, + // current locale and fallback locale. + // + // I18n.locales.get("de-DE"); + // // ["de-DE", "de", "en"] + // + // You can define custom rules for any locale. Just make sure you return a array + // containing all locales. + // + // // Default the Wookie locale to English. + // I18n.locales["wk"] = function(locale) { + // return ["en"]; + // }; + // + I18n.locales = {}; + + // Retrieve locales based on inline locale, current locale or default to + // I18n's detection. + I18n.locales.get = function(locale) { + var result = this[locale] || this[I18n.locale] || this["default"]; + + if (typeof(result) === "function") { + result = result(locale); + } + + if (isArray(result) === false) { + result = [result]; + } + + return result; + }; + + // The default locale list. + I18n.locales["default"] = function(locale) { + var locales = [] + , list = [] + , countryCode + , count + ; + + // Handle the inline locale option that can be provided to + // the `I18n.t` options. + if (locale) { + locales.push(locale); + } + + // Add the current locale to the list. + if (!locale && I18n.locale) { + locales.push(I18n.locale); + } + + // Add the default locale if fallback strategy is enabled. + if (I18n.fallbacks && I18n.defaultLocale) { + locales.push(I18n.defaultLocale); + } + + // Compute each locale with its country code. + // So this will return an array containing both + // `de-DE` and `de` locales. + locales.forEach(function(locale){ + countryCode = locale.split("-")[0]; + + if (!~list.indexOf(locale)) { + list.push(locale); + } + + if (I18n.fallbacks && countryCode && countryCode !== locale && !~list.indexOf(countryCode)) { + list.push(countryCode); + } + }); + + // No locales set? English it is. + if (!locales.length) { + locales.push("en"); + } + + return list; + }; + + // Hold pluralization rules. + I18n.pluralization = {}; + + // Return the pluralizer for a specific locale. + // If no specify locale is found, then I18n's default will be used. + I18n.pluralization.get = function(locale) { + return this[locale] || this[I18n.locale] || this["default"]; + }; + + // The default pluralizer rule. + // It detects the `zero`, `one`, and `other` scopes. + I18n.pluralization["default"] = function(count) { + switch (count) { + case 0: return ["zero", "other"]; + case 1: return ["one"]; + default: return ["other"]; + } + }; + + // Return current locale. If no locale has been set, then + // the current locale will be the default locale. + I18n.currentLocale = function() { + return this.locale || this.defaultLocale; + }; + + // Check if value is different than undefined and null; + I18n.isSet = function(value) { + return value !== undefined && value !== null; + }; + + // Find and process the translation using the provided scope and options. + // This is used internally by some functions and should not be used as an + // public API. + I18n.lookup = function(scope, options) { + options = this.prepareOptions(options); + + var locales = this.locales.get(options.locale).slice() + , requestedLocale = locales[0] + , locale + , scopes + , translations + ; + + scope = this.getFullScope(scope, options); + + while (locales.length) { + locale = locales.shift(); + scopes = scope.split(this.defaultSeparator); + translations = this.translations[locale]; + + if (!translations) { + continue; + } + + while (scopes.length) { + translations = translations[scopes.shift()]; + + if (translations === undefined || translations === null) { + break; + } + } + + if (translations !== undefined && translations !== null) { + return translations; + } + } + + if (this.isSet(options.defaultValue)) { + return options.defaultValue; + } + }; + + // Rails changed the way the meridian is stored. + // It started with `date.meridian` returning an array, + // then it switched to `time.am` and `time.pm`. + // This function abstracts this difference and returns + // the correct meridian or the default value when none is provided. + I18n.meridian = function() { + var time = this.lookup("time"); + var date = this.lookup("date"); + + if (time && time.am && time.pm) { + return [time.am, time.pm]; + } else if (date && date.meridian) { + return date.meridian; + } else { + return DATE.meridian; + } + }; + + // Merge serveral hash options, checking if value is set before + // overwriting any value. The precedence is from left to right. + // + // I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"}); + // #=> {name: "John Doe", role: "user"} + // + I18n.prepareOptions = function() { + var args = slice.call(arguments) + , options = {} + , subject + ; + + while (args.length) { + subject = args.shift(); + + if (typeof(subject) != "object") { + continue; + } + + for (var attr in subject) { + if (!subject.hasOwnProperty(attr)) { + continue; + } + + if (this.isSet(options[attr])) { + continue; + } + + options[attr] = subject[attr]; + } + } + + return options; + }; + + // Generate a list of translation options for default fallbacks. + // `defaultValue` is also deleted from options as it is returned as part of + // the translationOptions array. + I18n.createTranslationOptions = function(scope, options) { + var translationOptions = [{scope: scope}]; + + // Defaults should be an array of hashes containing either + // fallback scopes or messages + if (this.isSet(options.defaults)) { + translationOptions = translationOptions.concat(options.defaults); + } + + // Maintain support for defaultValue. Since it is always a message + // insert it in to the translation options as such. + if (this.isSet(options.defaultValue)) { + translationOptions.push({ message: options.defaultValue }); + delete options.defaultValue; + } + + return translationOptions; + }; + + // Translate the given scope with the provided options. + I18n.translate = function(scope, options) { + options = this.prepareOptions(options); + + var translationOptions = this.createTranslationOptions(scope, options); + + var translation; + // Iterate through the translation options until a translation + // or message is found. + var translationFound = + translationOptions.some(function(translationOption) { + if (this.isSet(translationOption.scope)) { + translation = this.lookup(translationOption.scope, options); + } else if (this.isSet(translationOption.message)) { + translation = translationOption.message; + } + + if (translation !== undefined && translation !== null) { + return true; + } + }, this); + + if (!translationFound) { + return this.missingTranslation(scope, options); + } + + if (typeof(translation) === "string") { + translation = this.interpolate(translation, options); + } else if (isObject(translation) && this.isSet(options.count)) { + translation = this.pluralize(options.count, translation, options); + } + + return translation; + }; + + // This function interpolates the all variables in the given message. + I18n.interpolate = function(message, options) { + options = this.prepareOptions(options); + var matches = message.match(this.placeholder) + , placeholder + , value + , name + , regex + ; + + if (!matches) { + return message; + } + + var value; + + while (matches.length) { + placeholder = matches.shift(); + name = placeholder.replace(this.placeholder, "$1"); + + if (this.isSet(options[name])) { + value = options[name].toString().replace(/\$/gm, "_#$#_"); + } else if (name in options) { + value = this.nullPlaceholder(placeholder, message, options); + } else { + value = this.missingPlaceholder(placeholder, message, options); + } + + regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}")); + message = message.replace(regex, value); + } + + return message.replace(/_#\$#_/g, "$"); + }; + + // Pluralize the given scope using the `count` value. + // The pluralized translation may have other placeholders, + // which will be retrieved from `options`. + I18n.pluralize = function(count, scope, options) { + options = this.prepareOptions(options); + var translations, pluralizer, keys, key, message; + + if (isObject(scope)) { + translations = scope; + } else { + translations = this.lookup(scope, options); + } + + if (!translations) { + return this.missingTranslation(scope, options); + } + + pluralizer = this.pluralization.get(options.locale); + keys = pluralizer(count); + + while (keys.length) { + key = keys.shift(); + + if (this.isSet(translations[key])) { + message = translations[key]; + break; + } + } + + options.count = String(count); + return this.interpolate(message, options); + }; + + // Return a missing translation message for the given parameters. + I18n.missingTranslation = function(scope, options) { + //guess intended string + if(this.missingBehaviour == 'guess'){ + //get only the last portion of the scope + var s = scope.split('.').slice(-1)[0]; + //replace underscore with space && camelcase with space and lowercase letter + return (this.missingTranslationPrefix.length > 0 ? this.missingTranslationPrefix : '') + + s.replace('_',' ').replace(/([a-z])([A-Z])/g, + function(match, p1, p2) {return p1 + ' ' + p2.toLowerCase()} ); + } + + var fullScope = this.getFullScope(scope, options); + var fullScopeWithLocale = [this.currentLocale(), fullScope].join(this.defaultSeparator); + + return '[missing "' + fullScopeWithLocale + '" translation]'; + }; + + // Return a missing placeholder message for given parameters + I18n.missingPlaceholder = function(placeholder, message, options) { + return "[missing " + placeholder + " value]"; + }; + + I18n.nullPlaceholder = function() { + return I18n.missingPlaceholder.apply(I18n, arguments); + }; + + // Format number using localization rules. + // The options will be retrieved from the `number.format` scope. + // If this isn't present, then the following options will be used: + // + // - `precision`: `3` + // - `separator`: `"."` + // - `delimiter`: `","` + // - `strip_insignificant_zeros`: `false` + // + // You can also override these options by providing the `options` argument. + // + I18n.toNumber = function(number, options) { + options = this.prepareOptions( + options + , this.lookup("number.format") + , NUMBER_FORMAT + ); + + var negative = number < 0 + , string = toFixed(Math.abs(number), options.precision).toString() + , parts = string.split(".") + , precision + , buffer = [] + , formattedNumber + , format = options.format || "%n" + , sign = negative ? "-" : "" + ; + + number = parts[0]; + precision = parts[1]; + + while (number.length > 0) { + buffer.unshift(number.substr(Math.max(0, number.length - 3), 3)); + number = number.substr(0, number.length -3); + } + + formattedNumber = buffer.join(options.delimiter); + + if (options.strip_insignificant_zeros && precision) { + precision = precision.replace(/0+$/, ""); + } + + if (options.precision > 0 && precision) { + formattedNumber += options.separator + precision; + } + + if (options.sign_first) { + format = "%s" + format; + } + else { + format = format.replace("%n", "%s%n"); + } + + formattedNumber = format + .replace("%u", options.unit) + .replace("%n", formattedNumber) + .replace("%s", sign) + ; + + return formattedNumber; + }; + + // Format currency with localization rules. + // The options will be retrieved from the `number.currency.format` and + // `number.format` scopes, in that order. + // + // Any missing option will be retrieved from the `I18n.toNumber` defaults and + // the following options: + // + // - `unit`: `"$"` + // - `precision`: `2` + // - `format`: `"%u%n"` + // - `delimiter`: `","` + // - `separator`: `"."` + // + // You can also override these options by providing the `options` argument. + // + I18n.toCurrency = function(number, options) { + options = this.prepareOptions( + options + , this.lookup("number.currency.format") + , this.lookup("number.format") + , CURRENCY_FORMAT + ); + + return this.toNumber(number, options); + }; + + // Localize several values. + // You can provide the following scopes: `currency`, `number`, or `percentage`. + // If you provide a scope that matches the `/^(date|time)/` regular expression + // then the `value` will be converted by using the `I18n.toTime` function. + // + // It will default to the value's `toString` function. + // + I18n.localize = function(scope, value, options) { + options || (options = {}); + + switch (scope) { + case "currency": + return this.toCurrency(value); + case "number": + scope = this.lookup("number.format"); + return this.toNumber(value, scope); + case "percentage": + return this.toPercentage(value); + default: + var localizedValue; + + if (scope.match(/^(date|time)/)) { + localizedValue = this.toTime(scope, value); + } else { + localizedValue = value.toString(); + } + + return this.interpolate(localizedValue, options); + } + }; + + // Parse a given `date` string into a JavaScript Date object. + // This function is time zone aware. + // + // The following string formats are recognized: + // + // yyyy-mm-dd + // yyyy-mm-dd[ T]hh:mm::ss + // yyyy-mm-dd[ T]hh:mm::ss + // yyyy-mm-dd[ T]hh:mm::ssZ + // yyyy-mm-dd[ T]hh:mm::ss+0000 + // yyyy-mm-dd[ T]hh:mm::ss+00:00 + // yyyy-mm-dd[ T]hh:mm::ss.123Z + // + I18n.parseDate = function(date) { + var matches, convertedDate, fraction; + // we have a date, so just return it. + if (typeof(date) == "object") { + return date; + }; + + matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})([\.,]\d{1,3})?)?(Z|\+00:?00)?/); + + if (matches) { + for (var i = 1; i <= 6; i++) { + matches[i] = parseInt(matches[i], 10) || 0; + } + + // month starts on 0 + matches[2] -= 1; + + fraction = matches[7] ? 1000 * ("0" + matches[7]) : null; + + if (matches[8]) { + convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction)); + } else { + convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction); + } + } else if (typeof(date) == "number") { + // UNIX timestamp + convertedDate = new Date(); + convertedDate.setTime(date); + } else if (date.match(/([A-Z][a-z]{2}) ([A-Z][a-z]{2}) (\d+) (\d+:\d+:\d+) ([+-]\d+) (\d+)/)) { + // This format `Wed Jul 20 13:03:39 +0000 2011` is parsed by + // webkit/firefox, but not by IE, so we must parse it manually. + convertedDate = new Date(); + convertedDate.setTime(Date.parse([ + RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$6, RegExp.$4, RegExp.$5 + ].join(" "))); + } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) { + // a valid javascript format with timezone info + convertedDate = new Date(); + convertedDate.setTime(Date.parse(date)); + } else { + // an arbitrary javascript string + convertedDate = new Date(); + convertedDate.setTime(Date.parse(date)); + } + + return convertedDate; + }; + + // Formats time according to the directives in the given format string. + // The directives begins with a percent (%) character. Any text not listed as a + // directive will be passed through to the output string. + // + // The accepted formats are: + // + // %a - The abbreviated weekday name (Sun) + // %A - The full weekday name (Sunday) + // %b - The abbreviated month name (Jan) + // %B - The full month name (January) + // %c - The preferred local date and time representation + // %d - Day of the month (01..31) + // %-d - Day of the month (1..31) + // %H - Hour of the day, 24-hour clock (00..23) + // %-H - Hour of the day, 24-hour clock (0..23) + // %I - Hour of the day, 12-hour clock (01..12) + // %-I - Hour of the day, 12-hour clock (1..12) + // %m - Month of the year (01..12) + // %-m - Month of the year (1..12) + // %M - Minute of the hour (00..59) + // %-M - Minute of the hour (0..59) + // %p - Meridian indicator (AM or PM) + // %S - Second of the minute (00..60) + // %-S - Second of the minute (0..60) + // %w - Day of the week (Sunday is 0, 0..6) + // %y - Year without a century (00..99) + // %-y - Year without a century (0..99) + // %Y - Year with century + // %z - Timezone offset (+0545) + // + I18n.strftime = function(date, format) { + var options = this.lookup("date") + , meridianOptions = I18n.meridian() + ; + + if (!options) { + options = {}; + } + + options = this.prepareOptions(options, DATE); + + var weekDay = date.getDay() + , day = date.getDate() + , year = date.getFullYear() + , month = date.getMonth() + 1 + , hour = date.getHours() + , hour12 = hour + , meridian = hour > 11 ? 1 : 0 + , secs = date.getSeconds() + , mins = date.getMinutes() + , offset = date.getTimezoneOffset() + , absOffsetHours = Math.floor(Math.abs(offset / 60)) + , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60) + , timezoneoffset = (offset > 0 ? "-" : "+") + + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes) + ; + + if (hour12 > 12) { + hour12 = hour12 - 12; + } else if (hour12 === 0) { + hour12 = 12; + } + + format = format.replace("%a", options.abbr_day_names[weekDay]); + format = format.replace("%A", options.day_names[weekDay]); + format = format.replace("%b", options.abbr_month_names[month]); + format = format.replace("%B", options.month_names[month]); + format = format.replace("%d", padding(day)); + format = format.replace("%e", day); + format = format.replace("%-d", day); + format = format.replace("%H", padding(hour)); + format = format.replace("%-H", hour); + format = format.replace("%I", padding(hour12)); + format = format.replace("%-I", hour12); + format = format.replace("%m", padding(month)); + format = format.replace("%-m", month); + format = format.replace("%M", padding(mins)); + format = format.replace("%-M", mins); + format = format.replace("%p", meridianOptions[meridian]); + format = format.replace("%S", padding(secs)); + format = format.replace("%-S", secs); + format = format.replace("%w", weekDay); + format = format.replace("%y", padding(year)); + format = format.replace("%-y", padding(year).replace(/^0+/, "")); + format = format.replace("%Y", year); + format = format.replace("%z", timezoneoffset); + + return format; + }; + + // Convert the given dateString into a formatted date. + I18n.toTime = function(scope, dateString) { + var date = this.parseDate(dateString) + , format = this.lookup(scope) + ; + + if (date.toString().match(/invalid/i)) { + return date.toString(); + } + + if (!format) { + return date.toString(); + } + + return this.strftime(date, format); + }; + + // Convert a number into a formatted percentage value. + I18n.toPercentage = function(number, options) { + options = this.prepareOptions( + options + , this.lookup("number.percentage.format") + , this.lookup("number.format") + , PERCENTAGE_FORMAT + ); + + return this.toNumber(number, options); + }; + + // Convert a number into a readable size representation. + I18n.toHumanSize = function(number, options) { + var kb = 1024 + , size = number + , iterations = 0 + , unit + , precision + ; + + while (size >= kb && iterations < 4) { + size = size / kb; + iterations += 1; + } + + if (iterations === 0) { + unit = this.t("number.human.storage_units.units.byte", {count: size}); + precision = 0; + } else { + unit = this.t("number.human.storage_units.units." + SIZE_UNITS[iterations]); + precision = (size - Math.floor(size) === 0) ? 0 : 1; + } + + options = this.prepareOptions( + options + , {unit: unit, precision: precision, format: "%n%u", delimiter: ""} + ); + + return this.toNumber(size, options); + }; + + I18n.getFullScope = function(scope, options) { + options = this.prepareOptions(options); + + // Deal with the scope as an array. + if (scope.constructor === Array) { + scope = scope.join(this.defaultSeparator); + } + + // Deal with the scope option provided through the second argument. + // + // I18n.t('hello', {scope: 'greetings'}); + // + if (options.scope) { + scope = [options.scope, scope].join(this.defaultSeparator); + } + + return scope; + }; + /** + * Merge obj1 with obj2 (shallow merge), without modifying inputs + * @param {Object} obj1 + * @param {Object} obj2 + * @returns {Object} Merged values of obj1 and obj2 + * + * In order to support ES3, `Object.prototype.hasOwnProperty.call` is used + * Idea is from: + * https://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8 + */ + I18n.extend = function ( obj1, obj2 ) { + var extended = {}; + var prop; + for (prop in obj1) { + if (Object.prototype.hasOwnProperty.call(obj1, prop)) { + extended[prop] = obj1[prop]; + } + } + for (prop in obj2) { + if (Object.prototype.hasOwnProperty.call(obj2, prop)) { + extended[prop] = obj2[prop]; + } + } + return extended; + }; + + // Set aliases, so we can save some typing. + I18n.t = I18n.translate; + I18n.l = I18n.localize; + I18n.p = I18n.pluralize; + + return I18n; +})); diff --git a/public/javascripts/i18n.js b/public/javascripts/i18n.js deleted file mode 100644 index 9797f5b..0000000 --- a/public/javascripts/i18n.js +++ /dev/null @@ -1,934 +0,0 @@ -// I18n.js -// ======= -// -// This small library provides the Rails I18n API on the Javascript. -// You don't actually have to use Rails (or even Ruby) to use I18n.js. -// Just make sure you export all translations in an object like this: -// -// I18n.translations.en = { -// hello: "Hello World" -// }; -// -// See tests for specific formatting like numbers and dates. -// - -;(function(factory) { - if (typeof module !== 'undefined' && module.exports) { - // Node/CommonJS - module.exports = factory(this); - } else if (typeof define === 'function' && define.amd) { - // AMD - var global=this; - define('i18n', function(){ return factory(global);}); - } else { - // Browser globals - this.I18n = factory(this); - } -}(function(global) { - "use strict"; - - // Use previously defined object if exists in current scope - var I18n = global && global.I18n || {}; - - // Just cache the Array#slice function. - var slice = Array.prototype.slice; - - // Apply number padding. - var padding = function(number) { - return ("0" + number.toString()).substr(-2); - }; - - // Improved toFixed number rounding function with support for unprecise floating points - // JavaScript's standard toFixed function does not round certain numbers correctly (for example 0.105 with precision 2). - var toFixed = function(number, precision) { - return decimalAdjust('round', number, -precision).toFixed(precision); - }; - - // Is a given variable an object? - // Borrowed from Underscore.js - var isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Is a given value an array? - // Borrowed from Underscore.js - var isArray = function(obj) { - if (Array.isArray) { - return Array.isArray(obj); - }; - return Object.prototype.toString.call(obj) === '[object Array]'; - }; - - var decimalAdjust = function(type, value, exp) { - // If the exp is undefined or zero... - if (typeof exp === 'undefined' || +exp === 0) { - return Math[type](value); - } - value = +value; - exp = +exp; - // If the value is not a number or the exp is not an integer... - if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { - return NaN; - } - // Shift - value = value.toString().split('e'); - value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); - // Shift back - value = value.toString().split('e'); - return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); - } - - // Set default days/months translations. - var DATE = { - day_names: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] - , abbr_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] - , month_names: [null, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] - , abbr_month_names: [null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] - , meridian: ["AM", "PM"] - }; - - // Set default number format. - var NUMBER_FORMAT = { - precision: 3 - , separator: "." - , delimiter: "," - , strip_insignificant_zeros: false - }; - - // Set default currency format. - var CURRENCY_FORMAT = { - unit: "$" - , precision: 2 - , format: "%u%n" - , sign_first: true - , delimiter: "," - , separator: "." - }; - - // Set default percentage format. - var PERCENTAGE_FORMAT = { - unit: "%" - , precision: 3 - , format: "%n%u" - , separator: "." - , delimiter: "" - }; - - // Set default size units. - var SIZE_UNITS = [null, "kb", "mb", "gb", "tb"]; - - // Other default options - var DEFAULT_OPTIONS = { - // Set default locale. This locale will be used when fallback is enabled and - // the translation doesn't exist in a particular locale. - defaultLocale: "en" - // Set the current locale to `en`. - , locale: "en" - // Set the translation key separator. - , defaultSeparator: "." - // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`. - , placeholder: /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm - // Set if engine should fallback to the default locale when a translation - // is missing. - , fallbacks: false - // Set the default translation object. - , translations: {} - // Set missing translation behavior. 'message' will display a message - // that the translation is missing, 'guess' will try to guess the string - , missingBehaviour: 'message' - // if you use missingBehaviour with 'message', but want to know that the - // string is actually missing for testing purposes, you can prefix the - // guessed string by setting the value here. By default, no prefix! - , missingTranslationPrefix: '' - }; - - I18n.reset = function() { - // Set default locale. This locale will be used when fallback is enabled and - // the translation doesn't exist in a particular locale. - this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; - - // Set the current locale to `en`. - this.locale = DEFAULT_OPTIONS.locale; - - // Set the translation key separator. - this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator; - - // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`. - this.placeholder = DEFAULT_OPTIONS.placeholder; - - // Set if engine should fallback to the default locale when a translation - // is missing. - this.fallbacks = DEFAULT_OPTIONS.fallbacks; - - // Set the default translation object. - this.translations = DEFAULT_OPTIONS.translations; - - // Set the default missing behaviour - this.missingBehaviour = DEFAULT_OPTIONS.missingBehaviour; - - // Set the default missing string prefix for guess behaviour - this.missingTranslationPrefix = DEFAULT_OPTIONS.missingTranslationPrefix; - - }; - - // Much like `reset`, but only assign options if not already assigned - I18n.initializeOptions = function() { - if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null) - this.defaultLocale = DEFAULT_OPTIONS.defaultLocale; - - if (typeof(this.locale) === "undefined" && this.locale !== null) - this.locale = DEFAULT_OPTIONS.locale; - - if (typeof(this.defaultSeparator) === "undefined" && this.defaultSeparator !== null) - this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator; - - if (typeof(this.placeholder) === "undefined" && this.placeholder !== null) - this.placeholder = DEFAULT_OPTIONS.placeholder; - - if (typeof(this.fallbacks) === "undefined" && this.fallbacks !== null) - this.fallbacks = DEFAULT_OPTIONS.fallbacks; - - if (typeof(this.translations) === "undefined" && this.translations !== null) - this.translations = DEFAULT_OPTIONS.translations; - }; - I18n.initializeOptions(); - - // Return a list of all locales that must be tried before returning the - // missing translation message. By default, this will consider the inline option, - // current locale and fallback locale. - // - // I18n.locales.get("de-DE"); - // // ["de-DE", "de", "en"] - // - // You can define custom rules for any locale. Just make sure you return a array - // containing all locales. - // - // // Default the Wookie locale to English. - // I18n.locales["wk"] = function(locale) { - // return ["en"]; - // }; - // - I18n.locales = {}; - - // Retrieve locales based on inline locale, current locale or default to - // I18n's detection. - I18n.locales.get = function(locale) { - var result = this[locale] || this[I18n.locale] || this["default"]; - - if (typeof(result) === "function") { - result = result(locale); - } - - if (isArray(result) === false) { - result = [result]; - } - - return result; - }; - - // The default locale list. - I18n.locales["default"] = function(locale) { - var locales = [] - , list = [] - , countryCode - , count - ; - - // Handle the inline locale option that can be provided to - // the `I18n.t` options. - if (locale) { - locales.push(locale); - } - - // Add the current locale to the list. - if (!locale && I18n.locale) { - locales.push(I18n.locale); - } - - // Add the default locale if fallback strategy is enabled. - if (I18n.fallbacks && I18n.defaultLocale) { - locales.push(I18n.defaultLocale); - } - - // Compute each locale with its country code. - // So this will return an array containing both - // `de-DE` and `de` locales. - locales.forEach(function(locale){ - countryCode = locale.split("-")[0]; - - if (!~list.indexOf(locale)) { - list.push(locale); - } - - if (I18n.fallbacks && countryCode && countryCode !== locale && !~list.indexOf(countryCode)) { - list.push(countryCode); - } - }); - - // No locales set? English it is. - if (!locales.length) { - locales.push("en"); - } - - return list; - }; - - // Hold pluralization rules. - I18n.pluralization = {}; - - // Return the pluralizer for a specific locale. - // If no specify locale is found, then I18n's default will be used. - I18n.pluralization.get = function(locale) { - return this[locale] || this[I18n.locale] || this["default"]; - }; - - // The default pluralizer rule. - // It detects the `zero`, `one`, and `other` scopes. - I18n.pluralization["default"] = function(count) { - switch (count) { - case 0: return ["zero", "other"]; - case 1: return ["one"]; - default: return ["other"]; - } - }; - - // Return current locale. If no locale has been set, then - // the current locale will be the default locale. - I18n.currentLocale = function() { - return this.locale || this.defaultLocale; - }; - - // Check if value is different than undefined and null; - I18n.isSet = function(value) { - return value !== undefined && value !== null; - }; - - // Find and process the translation using the provided scope and options. - // This is used internally by some functions and should not be used as an - // public API. - I18n.lookup = function(scope, options) { - options = this.prepareOptions(options); - - var locales = this.locales.get(options.locale).slice() - , requestedLocale = locales[0] - , locale - , scopes - , translations - ; - - scope = this.getFullScope(scope, options); - - while (locales.length) { - locale = locales.shift(); - scopes = scope.split(this.defaultSeparator); - translations = this.translations[locale]; - - if (!translations) { - continue; - } - - while (scopes.length) { - translations = translations[scopes.shift()]; - - if (translations === undefined || translations === null) { - break; - } - } - - if (translations !== undefined && translations !== null) { - return translations; - } - } - - if (this.isSet(options.defaultValue)) { - return options.defaultValue; - } - }; - - // Rails changed the way the meridian is stored. - // It started with `date.meridian` returning an array, - // then it switched to `time.am` and `time.pm`. - // This function abstracts this difference and returns - // the correct meridian or the default value when none is provided. - I18n.meridian = function() { - var time = this.lookup("time"); - var date = this.lookup("date"); - - if (time && time.am && time.pm) { - return [time.am, time.pm]; - } else if (date && date.meridian) { - return date.meridian; - } else { - return DATE.meridian; - } - }; - - // Merge serveral hash options, checking if value is set before - // overwriting any value. The precedence is from left to right. - // - // I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"}); - // #=> {name: "John Doe", role: "user"} - // - I18n.prepareOptions = function() { - var args = slice.call(arguments) - , options = {} - , subject - ; - - while (args.length) { - subject = args.shift(); - - if (typeof(subject) != "object") { - continue; - } - - for (var attr in subject) { - if (!subject.hasOwnProperty(attr)) { - continue; - } - - if (this.isSet(options[attr])) { - continue; - } - - options[attr] = subject[attr]; - } - } - - return options; - }; - - // Generate a list of translation options for default fallbacks. - // `defaultValue` is also deleted from options as it is returned as part of - // the translationOptions array. - I18n.createTranslationOptions = function(scope, options) { - var translationOptions = [{scope: scope}]; - - // Defaults should be an array of hashes containing either - // fallback scopes or messages - if (this.isSet(options.defaults)) { - translationOptions = translationOptions.concat(options.defaults); - } - - // Maintain support for defaultValue. Since it is always a message - // insert it in to the translation options as such. - if (this.isSet(options.defaultValue)) { - translationOptions.push({ message: options.defaultValue }); - delete options.defaultValue; - } - - return translationOptions; - }; - - // Translate the given scope with the provided options. - I18n.translate = function(scope, options) { - options = this.prepareOptions(options); - - var translationOptions = this.createTranslationOptions(scope, options); - - var translation; - // Iterate through the translation options until a translation - // or message is found. - var translationFound = - translationOptions.some(function(translationOption) { - if (this.isSet(translationOption.scope)) { - translation = this.lookup(translationOption.scope, options); - } else if (this.isSet(translationOption.message)) { - translation = translationOption.message; - } - - if (translation !== undefined && translation !== null) { - return true; - } - }, this); - - if (!translationFound) { - return this.missingTranslation(scope, options); - } - - if (typeof(translation) === "string") { - translation = this.interpolate(translation, options); - } else if (isObject(translation) && this.isSet(options.count)) { - translation = this.pluralize(options.count, translation, options); - } - - return translation; - }; - - // This function interpolates the all variables in the given message. - I18n.interpolate = function(message, options) { - options = this.prepareOptions(options); - var matches = message.match(this.placeholder) - , placeholder - , value - , name - , regex - ; - - if (!matches) { - return message; - } - - var value; - - while (matches.length) { - placeholder = matches.shift(); - name = placeholder.replace(this.placeholder, "$1"); - - if (this.isSet(options[name])) { - value = options[name].toString().replace(/\$/gm, "_#$#_"); - } else if (name in options) { - value = this.nullPlaceholder(placeholder, message, options); - } else { - value = this.missingPlaceholder(placeholder, message, options); - } - - regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}")); - message = message.replace(regex, value); - } - - return message.replace(/_#\$#_/g, "$"); - }; - - // Pluralize the given scope using the `count` value. - // The pluralized translation may have other placeholders, - // which will be retrieved from `options`. - I18n.pluralize = function(count, scope, options) { - options = this.prepareOptions(options); - var translations, pluralizer, keys, key, message; - - if (isObject(scope)) { - translations = scope; - } else { - translations = this.lookup(scope, options); - } - - if (!translations) { - return this.missingTranslation(scope, options); - } - - pluralizer = this.pluralization.get(options.locale); - keys = pluralizer(count); - - while (keys.length) { - key = keys.shift(); - - if (this.isSet(translations[key])) { - message = translations[key]; - break; - } - } - - options.count = String(count); - return this.interpolate(message, options); - }; - - // Return a missing translation message for the given parameters. - I18n.missingTranslation = function(scope, options) { - //guess intended string - if(this.missingBehaviour == 'guess'){ - //get only the last portion of the scope - var s = scope.split('.').slice(-1)[0]; - //replace underscore with space && camelcase with space and lowercase letter - return (this.missingTranslationPrefix.length > 0 ? this.missingTranslationPrefix : '') + - s.replace('_',' ').replace(/([a-z])([A-Z])/g, - function(match, p1, p2) {return p1 + ' ' + p2.toLowerCase()} ); - } - - var fullScope = this.getFullScope(scope, options); - var fullScopeWithLocale = [this.currentLocale(), fullScope].join(this.defaultSeparator); - - return '[missing "' + fullScopeWithLocale + '" translation]'; - }; - - // Return a missing placeholder message for given parameters - I18n.missingPlaceholder = function(placeholder, message, options) { - return "[missing " + placeholder + " value]"; - }; - - I18n.nullPlaceholder = function() { - return I18n.missingPlaceholder.apply(I18n, arguments); - }; - - // Format number using localization rules. - // The options will be retrieved from the `number.format` scope. - // If this isn't present, then the following options will be used: - // - // - `precision`: `3` - // - `separator`: `"."` - // - `delimiter`: `","` - // - `strip_insignificant_zeros`: `false` - // - // You can also override these options by providing the `options` argument. - // - I18n.toNumber = function(number, options) { - options = this.prepareOptions( - options - , this.lookup("number.format") - , NUMBER_FORMAT - ); - - var negative = number < 0 - , string = toFixed(Math.abs(number), options.precision).toString() - , parts = string.split(".") - , precision - , buffer = [] - , formattedNumber - , format = options.format || "%n" - , sign = negative ? "-" : "" - ; - - number = parts[0]; - precision = parts[1]; - - while (number.length > 0) { - buffer.unshift(number.substr(Math.max(0, number.length - 3), 3)); - number = number.substr(0, number.length -3); - } - - formattedNumber = buffer.join(options.delimiter); - - if (options.strip_insignificant_zeros && precision) { - precision = precision.replace(/0+$/, ""); - } - - if (options.precision > 0 && precision) { - formattedNumber += options.separator + precision; - } - - if (options.sign_first) { - format = "%s" + format; - } - else { - format = format.replace("%n", "%s%n"); - } - - formattedNumber = format - .replace("%u", options.unit) - .replace("%n", formattedNumber) - .replace("%s", sign) - ; - - return formattedNumber; - }; - - // Format currency with localization rules. - // The options will be retrieved from the `number.currency.format` and - // `number.format` scopes, in that order. - // - // Any missing option will be retrieved from the `I18n.toNumber` defaults and - // the following options: - // - // - `unit`: `"$"` - // - `precision`: `2` - // - `format`: `"%u%n"` - // - `delimiter`: `","` - // - `separator`: `"."` - // - // You can also override these options by providing the `options` argument. - // - I18n.toCurrency = function(number, options) { - options = this.prepareOptions( - options - , this.lookup("number.currency.format") - , this.lookup("number.format") - , CURRENCY_FORMAT - ); - - return this.toNumber(number, options); - }; - - // Localize several values. - // You can provide the following scopes: `currency`, `number`, or `percentage`. - // If you provide a scope that matches the `/^(date|time)/` regular expression - // then the `value` will be converted by using the `I18n.toTime` function. - // - // It will default to the value's `toString` function. - // - I18n.localize = function(scope, value, options) { - options || (options = {}); - - switch (scope) { - case "currency": - return this.toCurrency(value); - case "number": - scope = this.lookup("number.format"); - return this.toNumber(value, scope); - case "percentage": - return this.toPercentage(value); - default: - var localizedValue; - - if (scope.match(/^(date|time)/)) { - localizedValue = this.toTime(scope, value); - } else { - localizedValue = value.toString(); - } - - return this.interpolate(localizedValue, options); - } - }; - - // Parse a given `date` string into a JavaScript Date object. - // This function is time zone aware. - // - // The following string formats are recognized: - // - // yyyy-mm-dd - // yyyy-mm-dd[ T]hh:mm::ss - // yyyy-mm-dd[ T]hh:mm::ss - // yyyy-mm-dd[ T]hh:mm::ssZ - // yyyy-mm-dd[ T]hh:mm::ss+0000 - // yyyy-mm-dd[ T]hh:mm::ss+00:00 - // yyyy-mm-dd[ T]hh:mm::ss.123Z - // - I18n.parseDate = function(date) { - var matches, convertedDate, fraction; - // we have a date, so just return it. - if (typeof(date) == "object") { - return date; - }; - - matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})([\.,]\d{1,3})?)?(Z|\+00:?00)?/); - - if (matches) { - for (var i = 1; i <= 6; i++) { - matches[i] = parseInt(matches[i], 10) || 0; - } - - // month starts on 0 - matches[2] -= 1; - - fraction = matches[7] ? 1000 * ("0" + matches[7]) : null; - - if (matches[8]) { - convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction)); - } else { - convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction); - } - } else if (typeof(date) == "number") { - // UNIX timestamp - convertedDate = new Date(); - convertedDate.setTime(date); - } else if (date.match(/([A-Z][a-z]{2}) ([A-Z][a-z]{2}) (\d+) (\d+:\d+:\d+) ([+-]\d+) (\d+)/)) { - // This format `Wed Jul 20 13:03:39 +0000 2011` is parsed by - // webkit/firefox, but not by IE, so we must parse it manually. - convertedDate = new Date(); - convertedDate.setTime(Date.parse([ - RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$6, RegExp.$4, RegExp.$5 - ].join(" "))); - } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) { - // a valid javascript format with timezone info - convertedDate = new Date(); - convertedDate.setTime(Date.parse(date)); - } else { - // an arbitrary javascript string - convertedDate = new Date(); - convertedDate.setTime(Date.parse(date)); - } - - return convertedDate; - }; - - // Formats time according to the directives in the given format string. - // The directives begins with a percent (%) character. Any text not listed as a - // directive will be passed through to the output string. - // - // The accepted formats are: - // - // %a - The abbreviated weekday name (Sun) - // %A - The full weekday name (Sunday) - // %b - The abbreviated month name (Jan) - // %B - The full month name (January) - // %c - The preferred local date and time representation - // %d - Day of the month (01..31) - // %-d - Day of the month (1..31) - // %H - Hour of the day, 24-hour clock (00..23) - // %-H - Hour of the day, 24-hour clock (0..23) - // %I - Hour of the day, 12-hour clock (01..12) - // %-I - Hour of the day, 12-hour clock (1..12) - // %m - Month of the year (01..12) - // %-m - Month of the year (1..12) - // %M - Minute of the hour (00..59) - // %-M - Minute of the hour (0..59) - // %p - Meridian indicator (AM or PM) - // %S - Second of the minute (00..60) - // %-S - Second of the minute (0..60) - // %w - Day of the week (Sunday is 0, 0..6) - // %y - Year without a century (00..99) - // %-y - Year without a century (0..99) - // %Y - Year with century - // %z - Timezone offset (+0545) - // - I18n.strftime = function(date, format) { - var options = this.lookup("date") - , meridianOptions = I18n.meridian() - ; - - if (!options) { - options = {}; - } - - options = this.prepareOptions(options, DATE); - - var weekDay = date.getDay() - , day = date.getDate() - , year = date.getFullYear() - , month = date.getMonth() + 1 - , hour = date.getHours() - , hour12 = hour - , meridian = hour > 11 ? 1 : 0 - , secs = date.getSeconds() - , mins = date.getMinutes() - , offset = date.getTimezoneOffset() - , absOffsetHours = Math.floor(Math.abs(offset / 60)) - , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60) - , timezoneoffset = (offset > 0 ? "-" : "+") + - (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + - (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes) - ; - - if (hour12 > 12) { - hour12 = hour12 - 12; - } else if (hour12 === 0) { - hour12 = 12; - } - - format = format.replace("%a", options.abbr_day_names[weekDay]); - format = format.replace("%A", options.day_names[weekDay]); - format = format.replace("%b", options.abbr_month_names[month]); - format = format.replace("%B", options.month_names[month]); - format = format.replace("%d", padding(day)); - format = format.replace("%e", day); - format = format.replace("%-d", day); - format = format.replace("%H", padding(hour)); - format = format.replace("%-H", hour); - format = format.replace("%I", padding(hour12)); - format = format.replace("%-I", hour12); - format = format.replace("%m", padding(month)); - format = format.replace("%-m", month); - format = format.replace("%M", padding(mins)); - format = format.replace("%-M", mins); - format = format.replace("%p", meridianOptions[meridian]); - format = format.replace("%S", padding(secs)); - format = format.replace("%-S", secs); - format = format.replace("%w", weekDay); - format = format.replace("%y", padding(year)); - format = format.replace("%-y", padding(year).replace(/^0+/, "")); - format = format.replace("%Y", year); - format = format.replace("%z", timezoneoffset); - - return format; - }; - - // Convert the given dateString into a formatted date. - I18n.toTime = function(scope, dateString) { - var date = this.parseDate(dateString) - , format = this.lookup(scope) - ; - - if (date.toString().match(/invalid/i)) { - return date.toString(); - } - - if (!format) { - return date.toString(); - } - - return this.strftime(date, format); - }; - - // Convert a number into a formatted percentage value. - I18n.toPercentage = function(number, options) { - options = this.prepareOptions( - options - , this.lookup("number.percentage.format") - , this.lookup("number.format") - , PERCENTAGE_FORMAT - ); - - return this.toNumber(number, options); - }; - - // Convert a number into a readable size representation. - I18n.toHumanSize = function(number, options) { - var kb = 1024 - , size = number - , iterations = 0 - , unit - , precision - ; - - while (size >= kb && iterations < 4) { - size = size / kb; - iterations += 1; - } - - if (iterations === 0) { - unit = this.t("number.human.storage_units.units.byte", {count: size}); - precision = 0; - } else { - unit = this.t("number.human.storage_units.units." + SIZE_UNITS[iterations]); - precision = (size - Math.floor(size) === 0) ? 0 : 1; - } - - options = this.prepareOptions( - options - , {unit: unit, precision: precision, format: "%n%u", delimiter: ""} - ); - - return this.toNumber(size, options); - }; - - I18n.getFullScope = function(scope, options) { - options = this.prepareOptions(options); - - // Deal with the scope as an array. - if (scope.constructor === Array) { - scope = scope.join(this.defaultSeparator); - } - - // Deal with the scope option provided through the second argument. - // - // I18n.t('hello', {scope: 'greetings'}); - // - if (options.scope) { - scope = [options.scope, scope].join(this.defaultSeparator); - } - - return scope; - }; - /** - * Merge obj1 with obj2 (shallow merge), without modifying inputs - * @param {Object} obj1 - * @param {Object} obj2 - * @returns {Object} Merged values of obj1 and obj2 - * - * In order to support ES3, `Object.prototype.hasOwnProperty.call` is used - * Idea is from: - * https://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8 - */ - I18n.extend = function ( obj1, obj2 ) { - var extended = {}; - var prop; - for (prop in obj1) { - if (Object.prototype.hasOwnProperty.call(obj1, prop)) { - extended[prop] = obj1[prop]; - } - } - for (prop in obj2) { - if (Object.prototype.hasOwnProperty.call(obj2, prop)) { - extended[prop] = obj2[prop]; - } - } - return extended; - }; - - // Set aliases, so we can save some typing. - I18n.t = I18n.translate; - I18n.l = I18n.localize; - I18n.p = I18n.pluralize; - - return I18n; -})); diff --git a/public/javascripts/translations.js b/public/javascripts/translations.js index 0ed87ac..ab9a6f8 100644 --- a/public/javascripts/translations.js +++ b/public/javascripts/translations.js @@ -25,7 +25,7 @@ I18n.translations["bs"] = I18n.extend((I18n.translations["bs"] || {}), {"active_admin":{"access_denied":{"message":"Nemaš dopuštenja."},"any":"Bilo koji","batch_actions":{"action_label":"%{title} označene","button_label":"Grupne akcije","default_confirmation":"Jeste li sigurni da želite to učiniti?","delete_confirmation":"Jeste li sigurni da želite obrisati %{plural_model}?","labels":{"destroy":"Obriši"},"link":"Izradi jedan","selection_toggle_explanation":"(Izmijeni odabir)","succesfully_destroyed":{"few":"Uspješno su obrisana %{count} %{plural_model}","many":"Uspješno je obrisano %{count} %{plural_model}","one":"Uspješno je obrisan 1 %{model}","other":"Uspješno je obrisano %{count} %{plural_model}"}},"blank_slate":{"content":"Još uvijek ne postoji niti jedan zapis tipa %{resource_name}.","link":"Izradi jedan"},"cancel":"Odustani","comments":{"add":"Dodaj komentar","author":"Autor","author_missing":"Anoniman","author_type":"Tip autora","body":"Sadržaj","errors":{"empty_text":"Komentar nije spremljen, sadržaj je prazan."},"no_comments_yet":"Još nema komentara.","resource":"Objekt","resource_type":"Tip objekta","title":"Komentar","title_content":"Komentari (%{count})"},"dashboard":"Upravljačka ploča","dashboard_welcome":{"call_to_action":"Da biste dodali nove odjeljke na upravljačku ploču, pogledajte 'app/admin/dashboard.rb'","welcome":"Dobrodošli u Active Admin. Ovo je početna upravljačka ploča."},"delete":"Obriši","delete_confirmation":"Jeste li sigurni da želite ovo obrisati?","delete_model":"Obriši %{model}","details":"%{model} detalji","devise":{"change_password":{"submit":"Izmijeni lozinku","title":"Izmjena lozinke"},"email":{"title":"Email"},"links":{"forgot_your_password":"Zaboravljena lozinka?","sign_in":"Prijavi se","sign_in_with_omniauth_provider":"Prijavite se za %{provider}"},"login":{"remember_me":"Zapamti me","submit":"Prijavi se","title":"Prijava"},"password":{"title":"Lozinka"},"resend_confirmation_instructions":{"submit":"Pošalji","title":"Ponovno slanje uputstva za potvrdu"},"reset_password":{"submit":"Resetuj lozinku","title":"Zaboravljena lozinka?"},"sign_up":{"submit":"Registruj","title":"Registracija"},"subdomain":{"title":"Poddomena"},"unlock":{"submit":"Pošalji","title":"Ponovno slanje uputstva za otključavanje"},"username":{"title":"Korisničko ime"}},"download":"Spremi na računalo:","edit":"Uredi","edit_model":"Uredi %{model}","empty":"Prazno","filters":{"buttons":{"clear":"Ukloni filtere","filter":"Filtriraj"},"predicates":{"contains":"Sadrži","ends_with":"Završava sa","equals":"Jednako","greater_than":"Veće od","less_than":"Manje od","starts_with":"počinje s"}},"has_many_delete":"Obriši","has_many_new":"Dodaj novi %{model}","has_many_remove":"Ukloniti","index_list":{"block":"Lista","blog":"Blog","grid":"Rešetka","table":"Tabela"},"logout":"Odjavi se","main_content":"Molim Vas, implementirajte %{model}#main_content da biste prikazali sadržaj.","new_model":"Novi %{model}","next":"Sljedeći","pagination":{"empty":"Nije pronađen niti jedan %{model}.","entry":{"few":"zapisa","many":"zapisa","one":"zapis","other":"zapisa"},"multiple":"Prikazani %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E od ukupno \u003Cb\u003E%{total}\u003C/b\u003E","multiple_without_total":"Prikazani %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"Prikazan \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Prikazano \u003Cb\u003Esvih %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Prethodni","sidebars":{"filters":"Filtriranje"},"status_tag":{"no":"Nema","yes":"Da"},"view":"Pregledaj"}}); I18n.translations["da"] = I18n.extend((I18n.translations["da"] || {}), {"active_admin":{"access_denied":{"message":"Du har ikke rettigheder til at udføre denne handling."},"any":"Alle","batch_actions":{"action_label":"%{title} Valgte","button_label":"Batch Handlinger","default_confirmation":"Er du sikker på du vil gøre dette?","delete_confirmation":"Er du sikker på du vil slette disse %{plural_model}?","labels":{"destroy":"Slet"},"link":"Opret en","selection_toggle_explanation":"(Skift Selection)","succesfully_destroyed":{"one":"Vellykket ødelagt 1 %{model}","other":"Vellykket ødelagt %{count} %{plural_model}"}},"blank_slate":{"content":"Der er ingen %{resource_name} endnu.","link":"Opret"},"cancel":"Fortryd","comments":{"add":"Tilføj Kommentar","author":"forfatter","author_type":"forfatter type","body":"krop","errors":{"empty_text":"Kommentar blev ikke gemt, tekst var tom."},"no_comments_yet":"Ingen kommentarer endnu.","resource":"Resource","resource_type":"resource type","title":"Kommentar","title_content":"Kommentarer (%{count})"},"dashboard":"Kontrolpanel","dashboard_welcome":{"call_to_action":"Rediger 'app/admin/dashboard.rb' for at tilføje nye elementer til oversigtssiden.","welcome":"Velkommen til Active Admin. Dette er standardoversigtssiden."},"delete":"Slet","delete_confirmation":"Er du sikker på at du ønsker at slette?","delete_model":"Slet %{model}","details":"%{model} detaljer","devise":{"change_password":{"submit":"Skift min adgangskode","title":"Skift din adgangskode"},"links":{"forgot_your_password":"Glemt din adgangskode?","sign_in":"Log ind","sign_in_with_omniauth_provider":"Log ind med %{provider}"},"login":{"remember_me":"Husk mig","submit":"Login","title":"Login"},"reset_password":{"submit":"Nulstille min adgangskode","title":"Glemt din adgangskode?"},"unlock":{"submit":"Send oplåsnings instruktioner igen","title":"Send oplåsnings instruktioner igen"}},"download":"Download:","dropdown_actions":{"button_label":"Handlinger"},"edit":"Rediger","edit_model":"Rediger %{model}","empty":"Tom","filters":{"buttons":{"clear":"Ryd filtre","filter":"Filtrer"},"predicates":{"contains":"Indeholder","ends_with":"Slutter med","equals":"lig","greater_than":"større end","less_than":"mindre end","starts_with":"Begynder med"}},"has_many_delete":"Slet","has_many_new":"Tilføj ny(t) %{model}","has_many_remove":"Fjern","index_list":{"block":"Liste","blog":"Blog","grid":"Gitter","table":"Tabel"},"logout":"Log ud","main_content":"Implementer venligst %{model}#main_content for at vise noget indhold.","new_model":"Ny(t) %{model}","next":"Næste","pagination":{"empty":"Ingen %{model} fundet","entry":{"one":"post","other":"poster"},"multiple":"Viser %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E af \u003Cb\u003E%{total}\u003C/b\u003E i alt","multiple_without_total":"Viser %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"Viser \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Viser \u003Cb\u003Ealle %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Forrige","sidebars":{"filters":"Filtre"},"status_tag":{"no":"Nej","yes":"Ja"},"view":"Vis"}}); I18n.translations["de-CH"] = I18n.extend((I18n.translations["de-CH"] || {}), {"active_admin":{"any":"Alle","batch_actions":{"action_label":"%{title} ausgewählte","button_label":"Stapelverarbeitung","default_confirmation":"Bist du sicher, dass Sie dies tun wollen?","delete_confirmation":"Sind Sie sicher dass sie diese %{plural_model} löschen wollen?","labels":{"destroy":"Lösche"},"link":"erstellen","selection_toggle_explanation":"(Auswahl umschalten)","succesfully_destroyed":{"one":"Erfolgreich 1 %{model} gelöscht","other":"Erfolgreich %{count} %{plural_model} gelöscht"}},"blank_slate":{"content":"Es gibt noch keine %{resource_name}.","link":"Erstellen"},"cancel":"Abbrechen","comments":{"add":"Kommentar hinzufügen","author":"Autor","body":"Inhalt","delete":"Löschen","delete_confirmation":"Sind Sie sicher dass sie diesen Kommentar löschen wollen?","errors":{"empty_text":"Der Kommentar wurde nicht gespeichert, da der Text fehlt."},"no_comments_yet":"Es gibt noch keine Kommentare.","resource":"Resource","title":"Kommentar","title_content":"Kommentare (%{count})"},"dashboard":"Übersicht","dashboard_welcome":{"call_to_action":"Siehe 'app/admin/dashboards.rb', um Übersichts-Bereiche hinzuzufügen.","welcome":"Willkommen in Active Admin. Dies ist die Standard-Übersichtsseite."},"delete":"Löschen","delete_confirmation":"Wollen Sie dieses Element wirklich löschen?","delete_model":"%{model} löschen","details":"%{model} Details","devise":{"change_password":{"submit":"Mein Passwort ändern","title":"Ändern Sie Ihr Passwort"},"links":{"forgot_your_password":"Passwort vergessen?","resend_confirmation_instructions":"Bestätigungsanweisung erneut senden","resend_unlock_instructions":"Entsperrungsanweisung erneut senden","sign_in":"Anmeldung","sign_in_with_omniauth_provider":"Anmeldung mit %{provider}","sign_up":"Registrieren"},"login":{"remember_me":"erinnere dich an mich","submit":"Login","title":"Login"},"reset_password":{"submit":"Mein Passwort zurücksetzen","title":"Passwort vergessen?"}},"download":"Herunterladen:","dropdown_actions":{"button_label":"Aktionen"},"edit":"Bearbeiten","edit_model":"%{model} bearbeiten","empty":"Leer","filters":{"buttons":{"clear":"Filter entfernen","filter":"Filtern"},"predicates":{"contains":"Enthält","ends_with":"Endet mit","equals":"Gleich","greater_than":"Grösser als","less_than":"Kleiner als","starts_with":"Beginnt mit"}},"has_many_delete":"Löschen","has_many_new":"%{model} hinzufügen","has_many_remove":"Entfernen","logout":"Abmelden","main_content":"Bitte implementieren Sie %{model}#main_content, um Inhalte anzuzeigen.","new_model":"%{model} erstellen","next":"Weiter","pagination":{"empty":"Keine %{model} gefunden","entry":{"one":"Eintrag","other":"Einträge"},"multiple":"Zeige %{model} \u003Cb\u003E%{from}\u0026nbsp;–\u0026nbsp;%{to}\u003C/b\u003E von \u003Cb\u003E%{total}\u003C/b\u003E","multiple_without_total":"Zeige %{model} \u003Cb\u003E%{from}\u0026nbsp;–\u0026nbsp;%{to}\u003C/b\u003E","one":"Zeige \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Zeige \u003Cb\u003Ealle %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Zurück","sidebars":{"filters":"Filter"},"status_tag":{"no":"Nicht","yes":"Ja"},"unsupported_browser":{"headline":"ActiveAdmin unterstützt nicht länger den Internet Explorer in Version 8 oder niedriger.","recommendation":"Wir empfehlen die Nutzung von \u003Ca href=\"http://windows.microsoft.com/ie\"\u003EInternet Explorer\u003C/a\u003E, \u003Ca href=\"https://chrome.google.com/\"\u003EGoogle Chrome\u003C/a\u003E, oder \u003Ca href=\"https://mozilla.org/firefox/\"\u003EFirefox\u003C/a\u003E.","turn_off_compatibility_view":"Wenn sie IE 9 oder neuer benutzen, stellen sie sicher das sie den \u003Ca href=\"http://windows.microsoft.com/en-US/windows7/webpages-look-incorrect-in-Internet-Explorer\"\u003E\"Kompatibilitätsansicht\" ausgeschaltet\u003C/a\u003E haben."},"view":"Anzeigen"}}); -I18n.translations["en-GB"] = I18n.extend((I18n.translations["en-GB"] || {}), {"active_admin":{"any":"Any","batch_actions":{"action_label":"%{title} Selected","button_label":"Batch Actions","default_confirmation":"Are you sure you want to do this?","delete_confirmation":"Are you sure you want to delete these %{plural_model}?","labels":{"destroy":"Delete"},"link":"Create one","selection_toggle_explanation":"(Toggle Selection)","succesfully_destroyed":{"one":"Successfully destroyed 1 %{model}","other":"Successfully destroyed %{count} %{plural_model}"}},"blank_slate":{"content":"There are no %{resource_name} yet.","link":"Create one"},"cancel":"Cancel","comments":{"add":"Add Comment","author":"Author","author_missing":"Anonymous","body":"Body","errors":{"empty_text":"Comment wasn't saved, text was empty."},"no_comments_yet":"No comments yet.","resource":"Resource","title":"Comment","title_content":"Comments (%{count})"},"dashboard":"Dashboard","dashboard_welcome":{"call_to_action":"To add dashboard sections, checkout 'app/admin/dashboards.rb'","welcome":"Welcome to Active Admin. This is the default dashboard page."},"delete":"Delete","delete_confirmation":"Are you sure you want to delete this?","delete_model":"Delete %{model}","details":"%{model} Details","devise":{"change_password":{"submit":"Change my password","title":"Change your password"},"links":{"forgot_your_password":"Forgot your password?","resend_unlock_instructions":"Re-send unlock instructions","sign_in":"Sign in","sign_in_with_omniauth_provider":"Sign in with %{provider}"},"login":{"remember_me":"Remember me","submit":"Login","title":"Login"},"resend_confirmation_instructions":{"submit":"Resend confirmation instructions","title":"Resend confirmation instructions"},"reset_password":{"submit":"Reset My Password","title":"Forgot your password?"}},"download":"Download:","dropdown_actions":{"button_label":"Actions"},"edit":"Edit","edit_model":"Edit %{model}","empty":"Empty","filters":{"buttons":{"clear":"Clear Filters","filter":"Filter"},"predicates":{"contains":"Contains","ends_with":"Ends with","equals":"Equals","greater_than":"Greater than","less_than":"Less than","starts_with":"Starts with"}},"has_many_delete":"Delete","has_many_new":"Add New %{model}","has_many_remove":"Remove","logout":"Logout","main_content":"Please implement %{model}#main_content to display content.","new_model":"New %{model}","next":"Next","pagination":{"empty":"No %{model} found","entry":{"one":"entry","other":"entries"},"multiple":"Displaying %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E of \u003Cb\u003E%{total}\u003C/b\u003E in total","multiple_without_total":"Displaying %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"Displaying \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Displaying \u003Cb\u003Eall %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Previous","sidebars":{"filters":"Filters"},"status_tag":{"no":"No","yes":"Yes"},"view":"View"}}); +I18n.translations["en_GB"] = I18n.extend((I18n.translations["en_GB"] || {}), {"active_admin":{"any":"Any","batch_actions":{"action_label":"%{title} Selected","button_label":"Batch Actions","default_confirmation":"Are you sure you want to do this?","delete_confirmation":"Are you sure you want to delete these %{plural_model}?","labels":{"destroy":"Delete"},"link":"Create one","selection_toggle_explanation":"(Toggle Selection)","succesfully_destroyed":{"one":"Successfully destroyed 1 %{model}","other":"Successfully destroyed %{count} %{plural_model}"}},"blank_slate":{"content":"There are no %{resource_name} yet.","link":"Create one"},"cancel":"Cancel","comments":{"add":"Add Comment","author":"Author","author_missing":"Anonymous","body":"Body","errors":{"empty_text":"Comment wasn't saved, text was empty."},"no_comments_yet":"No comments yet.","resource":"Resource","title":"Comment","title_content":"Comments (%{count})"},"dashboard":"Dashboard","dashboard_welcome":{"call_to_action":"To add dashboard sections, checkout 'app/admin/dashboards.rb'","welcome":"Welcome to Active Admin. This is the default dashboard page."},"delete":"Delete","delete_confirmation":"Are you sure you want to delete this?","delete_model":"Delete %{model}","details":"%{model} Details","devise":{"change_password":{"submit":"Change my password","title":"Change your password"},"links":{"forgot_your_password":"Forgot your password?","resend_unlock_instructions":"Re-send unlock instructions","sign_in":"Sign in","sign_in_with_omniauth_provider":"Sign in with %{provider}"},"login":{"remember_me":"Remember me","submit":"Login","title":"Login"},"resend_confirmation_instructions":{"submit":"Resend confirmation instructions","title":"Resend confirmation instructions"},"reset_password":{"submit":"Reset My Password","title":"Forgot your password?"}},"download":"Download:","dropdown_actions":{"button_label":"Actions"},"edit":"Edit","edit_model":"Edit %{model}","empty":"Empty","filters":{"buttons":{"clear":"Clear Filters","filter":"Filter"},"predicates":{"contains":"Contains","ends_with":"Ends with","equals":"Equals","greater_than":"Greater than","less_than":"Less than","starts_with":"Starts with"}},"has_many_delete":"Delete","has_many_new":"Add New %{model}","has_many_remove":"Remove","logout":"Logout","main_content":"Please implement %{model}#main_content to display content.","new_model":"New %{model}","next":"Next","pagination":{"empty":"No %{model} found","entry":{"one":"entry","other":"entries"},"multiple":"Displaying %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E of \u003Cb\u003E%{total}\u003C/b\u003E in total","multiple_without_total":"Displaying %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"Displaying \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Displaying \u003Cb\u003Eall %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Previous","sidebars":{"filters":"Filters"},"status_tag":{"no":"No","yes":"Yes"},"view":"View"}}); I18n.translations["es-MX"] = I18n.extend((I18n.translations["es-MX"] || {}), {"active_admin":{"any":"Cualquiera","batch_actions":{"action_label":"%{title} seleccionado","button_label":"Acciones en masa","default_confirmation":"¿Seguro que quieres hacer esto?","delete_confirmation":"Eliminar %{plural_model}: ¿Está seguro?","labels":{"destroy":"Borrar"},"link":"Añadir","selection_toggle_explanation":"(Cambiar selección)","succesfully_destroyed":{"one":"Se ha destruido 1 %{model} con éxito","other":"Se han destruido %{count} %{plural_model} con éxito"}},"blank_slate":{"content":"No hay %{resource_name} aún.","link":"Añadir"},"cancel":"Cancelar","comments":{"add":"Comentar","author":"Autor","body":"Cuerpo","errors":{"empty_text":"El comentario no fue guardado, el texto estaba vacío."},"no_comments_yet":"Aún sin comentarios.","resource":"Recurso","title":"Comentario","title_content":"Comentarios (%{count})"},"dashboard":"Inicio","dashboard_welcome":{"call_to_action":"Para agregar secciones edite 'app/admin/dashboard.rb'","welcome":"Bienvenido a Active Admin. Esta es la página de inicio predeterminada."},"delete":"Eliminar","delete_confirmation":"¿Está seguro de que quiere eliminar esto?","delete_model":"Eliminar %{model}","details":"Detalles de %{model}","devise":{"change_password":{"submit":"Cambiar mi contraseña","title":"Cambie su contraseña"},"links":{"forgot_your_password":"¿Olvidó su contraseña?","sign_in":"Registrarse","sign_in_with_omniauth_provider":"Conéctate con %{provider}"},"login":{"remember_me":"Recordarme","submit":"Iniciar Sesión","title":"Iniciar Sesión"},"reset_password":{"submit":"Restablecer mi contraseña","title":"¿Olvidó su contraseña?"}},"download":"Descargar:","dropdown_actions":{"button_label":"Acciones"},"edit":"Editar","edit_model":"Editar %{model}","empty":"Vacío","filters":{"buttons":{"clear":"Quitar Filtros","filter":"Filtrar"},"predicates":{"contains":"Contiene","ends_with":"Termina con","equals":"Igual a","greater_than":"Mayor que","less_than":"Menor que","starts_with":"Empieza con"}},"has_many_delete":"Eliminar","has_many_new":"Añadir %{model}","has_many_remove":"Quitar","index_list":{"block":"Lista","blog":"Blog","grid":"Cuadrícula","table":"Tabla"},"logout":"Salir","main_content":"Por favor implemente %{model}#main_content para mostrar contenido.","new_model":"Añadir %{model}","next":"Siguiente","pagination":{"empty":"No se han encontrado %{model}","multiple":"Mostrando %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E de un total de \u003Cb\u003E%{total}\u003C/b\u003E","one":"Mostrando \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Mostrando \u003Cb\u003Eun total de %{n}\u003C/b\u003E %{model}"},"powered_by":"Powered by %{active_admin} %{version}","previous":"Anterior","sidebars":{"filters":"Filtros"},"status_tag":{"no":"No","yes":"Sí"},"view":"Ver"}}); I18n.translations["fa"] = I18n.extend((I18n.translations["fa"] || {}), {"active_admin":{"access_denied":{"message":"شما دسترسی لازم برای انجام این عملیات را ندارید."},"any":"هرکدام","batch_actions":{"action_label":"%{title} انتخاب شده است","button_label":"عملیات‌های دسته‌ای","default_confirmation":"آیا برای اجرای این عملیات اطمینان دارید؟","delete_confirmation":"آیا برای حذف همه رکوردهای %{plural_model} اطمینان دارید؟","labels":{"destroy":"حذف"},"link":"ایجاد یک رکورد جدید","selection_toggle_explanation":"(انتخاب‌ها برعکس شوند)","succesfully_destroyed":{"one":"1 %{model} با موفقیت حذف شد","other":"%{count} %{plural_model} با موفقت حذف شدند."}},"blank_slate":{"content":"هنوز هیچ رکوردی از %{resource_name} درج نشده.","link":"درج اولین رکورد"},"cancel":"لغو","comments":{"add":"افزودن کامنت","author":"ایجاد کننده","author_missing":"بی‌نام","author_type":"نوع ایجاد کننده","body":"بدنه","errors":{"empty_text":"کامنت درج نشد، متن کامنت خالی بود."},"no_comments_yet":"هنوز هیچ کامنتی نوشته نشده.","resource":"رکورد","resource_type":"نوع رکورد","title":"کامنت","title_content":"کامنت‌ها (%{count})"},"dashboard":"داشبرد","dashboard_welcome":{"call_to_action":"برای اضافه کردن قسمت‌هایی به داشبرد اینجا را چک کنید: 'app/admin/dashboard.rb'","welcome":"به اکتیو ادمین خوش آمدید. این صفحه اول داشبرد است."},"delete":"حذف","delete_confirmation":"آیا برای حذف این آیتم اطمینان دارید؟","delete_model":"حذف %{model}","details":"جزئیات %{model}","devise":{"change_password":{"submit":"تغییر کلمه عبور","title":"تغییر کلمه عبور"},"email":{"title":"ایمیل"},"links":{"forgot_your_password":"کلمه عبور را فراموش کرده‌اید؟","sign_in":"ورود","sign_in_with_omniauth_provider":"ورود با حساب %{provider}"},"login":{"remember_me":"مرا به خاطر بسپار","submit":"ورود","title":"ورود"},"password":{"title":"کلمه‌عبور"},"resend_confirmation_instructions":{"submit":"ارسال مجدد تاییدیه ایمیل","title":"ارسال مجدد تاییدیه ایمیل"},"reset_password":{"submit":"دریافت کلمه عبور جدید","title":"کلمه عبور را فراموش کرده‌اید؟"},"sign_up":{"submit":"ثبت‌نام","title":"ثبت‌نام"},"subdomain":{"title":"Subdomain"},"unlock":{"submit":"ارسال مجدد دستورالعمل بازگشایی حساب کاربری","title":"ارسال مجدد دستورالعمل بازگشایی حساب کاربری"},"username":{"title":"نام کاربری"}},"download":"دریافت:","dropdown_actions":{"button_label":"عملیات"},"edit":"ویرایش","edit_model":"ویرایش %{model}","empty":"خالی","filters":{"buttons":{"clear":"پاک کردن فیلتر","filter":"فیلتر"},"predicates":{"contains":"شامل","ends_with":"پایان با","equals":"برابر با","greater_than":"بزرگتر از","less_than":"کوچکتر از","starts_with":"شروع با"}},"has_many_delete":"حذف","has_many_new":"اضافه کردن %{model} جدید","has_many_remove":"حذف","index_list":{"block":"لیست","blog":"وبلاگ","grid":"گرید","table":"جدول"},"logout":"خروج","main_content":"لطفا %{model}#main_content را پیاده سازی کنید تا محتوی نمایش داده شود.","new_model":"%{model} جدید","next":"بعدی","pagination":{"empty":"هیچ رکورد %{model} یافت نشد","entry":{"one":"آیتم","other":"آیتم‌ها"},"multiple":"نمایش %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E از کل \u003Cb\u003E%{total}\u003C/b\u003E رکورد","multiple_without_total":"نمایش %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"نمایش \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"نمایش \u003Cb\u003Eهمه %{n}\u003C/b\u003E %{model}"},"powered_by":"قدرت گرفته از %{active_admin} %{version}","previous":"قبلی","sidebars":{"filters":"فیلتر‌ها"},"status_tag":{"no":"بدون","yes":"بله"},"view":"نمایش"}}); I18n.translations["fi"] = I18n.extend((I18n.translations["fi"] || {}), {"active_admin":{"access_denied":{"message":"Sinulla ei ole oikeuksia suorittaa yrittämääsi toimintoa."},"any":"mikä vain","batch_actions":{"action_label":"%{title} Valittu","button_label":"Toimet","default_confirmation":"Oletko varma, että haluat tehdä tämän?","delete_confirmation":"Oletko varma, että haluat poistaa nämä %{plural_model}:t?","labels":{"destroy":"Poista"},"link":"Luo","selection_toggle_explanation":"(Vaihda valintaa)","succesfully_destroyed":{"one":"1 %{model} poistettu","other":"%{count} %{plural_model}:a poistettu"}},"blank_slate":{"content":"Järjestelmässä ei ole yhtään %{resource_name}:ia vielä.","link":"Luo ensimmäinen"},"cancel":"Peruuta","comments":{"add":"Lisää kommentti","author":"Luoja","author_type":"Luoja-tyyppi","body":"Runko","errors":{"empty_text":"Kommenttia ei pystytty tallentamaan, et kirjoittanut kommenttitekstiä."},"no_comments_yet":"Ei kommentteja.","resource":"Resurssi","resource_type":"Resurssityyppi","title":"Kommentti","title_content":"Kommentteja (%{count})"},"dashboard":"Etusivu","dashboard_welcome":{"call_to_action":"Lisätäksesi etusivun osioita katso: 'app/admin/dashboard.rb'","welcome":"Tervetuloa! Tämä on Active Adminin oletusetusivu."},"delete":"Poista","delete_confirmation":"Oletko varma, että haluat poistaa tämän?","delete_model":"Poista %{model}","details":"%{model} Tiedot","devise":{"change_password":{"submit":"Vaihda salasana","title":"Vaihda salasana"},"email":{"title":"Sähköposti"},"links":{"forgot_your_password":"Unohtunut salasana?","sign_in":"Kirjaudu sisään","sign_in_with_omniauth_provider":"Kirjaudu sisään %{provider}:ia käyttäen"},"login":{"remember_me":"Muista minut","submit":"Kirjaudu sisään","title":"Sisäänkirjautuminen"},"password":{"title":"Salasana"},"reset_password":{"submit":"Resetoi salasana","title":"Unohtunut salasana?"},"subdomain":{"title":"Subdomain"},"unlock":{"submit":"Lähetä ohjeet lukituksen poistoon","title":"Lähetä ohjeet lukituksen poistoon"},"username":{"title":"Käyttäjänimi"}},"download":"Lataa:","dropdown_actions":{"button_label":"Acciones"},"edit":"Muokkaa","edit_model":"Muokaa %{model}","empty":"Tyhjä","filters":{"buttons":{"clear":"Tyhjennä valinnat","filter":"Hae"},"predicates":{"contains":"Sisältää","ends_with":"Päättyy","equals":"On yhtä kuin","greater_than":"Suurempi kuin","less_than":"Pienempi kuin","starts_with":"Alkaa"}},"has_many_delete":"Poista","has_many_new":"Lisää uusi %{model}","has_many_remove":"Poista","index_list":{"block":"Lista","blog":"Blogi","grid":"Ruudukko","table":"Taulukko"},"logout":"Kirjaudu ulos","main_content":"Ole hyvä, käytä %{model}#main_content:ia nähdäksesi jotain.","new_model":"Uusi %{model}","next":"Seuraava","pagination":{"empty":"%{model}:ia ei löytynyt","entry":{"one":"syöte","other":"syötteet"},"multiple":"Näytetään %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E (yhteensä \u003Cb\u003E%{total}\u003C/b\u003E)","multiple_without_total":"Näytetään %{model} \u003Cb\u003E%{from}\u0026nbsp;-\u0026nbsp;%{to}\u003C/b\u003E","one":"Näytetään \u003Cb\u003E1\u003C/b\u003E %{model}","one_page":"Näytetään \u003Cb\u003Ekaikki %{n}\u003C/b\u003E %{model}:it"},"powered_by":"Käyttää %{active_admin} %{version}:ia","previous":"Edellinen","sidebars":{"filters":"Haku"},"status_tag":{"no":"Ei","yes":"Kyllä"},"view":"Katso"}}); diff --git a/test/configuration_test.rb b/test/configuration_test.rb new file mode 100644 index 0000000..05c9622 --- /dev/null +++ b/test/configuration_test.rb @@ -0,0 +1,24 @@ +require 'test_helper' + +class ConfigurationTest < ActionDispatch::IntegrationTest + + # -------------------------------------------------------------------- + test "Make sure that all of the example YAML files have been setup properly" do + # Check for YAML configs + ['database.yml', 'branding.yml', 'secrets.yml'].each do |yml| + assert File.exist?("./config/#{yml}"), "Was expecting to find ./config/#{yml}" + end + + # Check for initializers + ['contact_us.rb', 'devise.rb', 'recaptcha.rb', 'wicked_pdf.rb'].each do |rb| + assert File.exist?("./config/initializers/#{rb}"), "Was expecting to find ./config/initializers/#{rb}" + end + end + + # -------------------------------------------------------------------- + test "Make sure that the config/branding.yml contains the managing Org's info" do + abbr = Rails.configuration.branding[:organisation][:abbreviation] + assert_not abbr.nil?, "expected the config/branding.yml to define the managing Org's abbreviation in organisation.abbreviation!" + assert_not Org.find_by(abbreviation: abbr).nil?, "Was expecting the organisation.abbreviation listed in config/branding.yml, '#{abbr}', to match the one from db/seeds.rb, '#{Org.first.abbreviation}'" + end +end \ No newline at end of file diff --git a/test/fixtures/.gitkeep b/test/fixtures/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/test/fixtures/.gitkeep +++ /dev/null diff --git a/test/fixtures/answers.yml b/test/fixtures/answers.yml deleted file mode 100644 index af9ebc8..0000000 --- a/test/fixtures/answers.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -one: - text: MyText - plan_id: 1 - user_id: 1 - question_id: 1 - -#two: -# text: MyText -# plan_id: 1 -# user_id: 1 -# question_id: 1 diff --git a/test/fixtures/comments.yml b/test/fixtures/comments.yml deleted file mode 100644 index 69b84d4..0000000 --- a/test/fixtures/comments.yml +++ /dev/null @@ -1,11 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -one: - user_id: 1 - question_id: 1 - text: MyText - -two: - user_id: 1 - question_id: 1 - text: MyText diff --git a/test/fixtures/dmptemplates.yml b/test/fixtures/dmptemplates.yml deleted file mode 100644 index 5e0fa48..0000000 --- a/test/fixtures/dmptemplates.yml +++ /dev/null @@ -1,70 +0,0 @@ -# Produces: -# ----------------------------- -# cc_template <-- belongs to organisation: cc -# cc_template_unpublished <-- belongs to organisation: cc -# -# funder_template_1 <-- belongs to organisation: funder -# funder_template_2 <-- belongs to organisation: funder -# funder_template_unpublished <-- belongs to organisation: funder -# -# complete_template <-- belongs to organisation: complete -# -# institution_[1..2]_template <-- belongs to organisation: institution_X -# institution_[1..2]_template_unpublished <-- belongs to organisation: institution_X -# -# school_[1..2]_template <-- belongs to organisation: school_X -# school_[1..2]_template_unpublished <-- belongs to organisation: school_X -# -# project_[1..2]_template <-- belongs to organisation: project_X -# project_[1..2]_template_unpublished <-- belongs to organisation: project_X -# - -# Import organisation_types.yml so that we can dynamically generate organisations -<% organisation_types = YAML::load(ERB.new(File.read('./test/fixtures/organisation_types.yml')).result) %> - -cc_template: - title: "Curation Centre Default Template" - description: "The default template" - published: true - organisation: curation_center - locale: en-UK - is_default: true - -cc_template_unpublished: - title: "Curation Centre Default Template" - description: "The default template" - published: false - organisation: curation_center - locale: en-UK - is_default: true - -<% 3.times do |n| %> -funder_template_<%= (n == 1 ? 'unpublished' : n + 1) %>: - title: <%= "Funder Template #{(n == 1 ? 'unpublished' : n + 1)}" %> - published: <%= (n != 1) %> - organisation: funder - locale: en-UK -<% end %> - -complete_template: - title: "Complete Organisation's Template" - description: "The template for the complete organisation" - published: true - organisation: complete - locale: en-UK - -<% organisation_types.each do |lbl, obj| %> - <% unless ['funder', 'organisation'].include?(lbl) %> - <% 2.times do |x| %> - <% 2.times do |y| %> - -<%= lbl %>_<%= x + 1 %>_template<%= (y == 0 ? '' : '_unpublished') %>: - title: <%= "#{obj['name']} #{x + 1} Template #{(y == 0 ? '' : 'Unpublished')}" %> - published: <%= (y == 0) %> - organisation: <%= lbl %>_<%= x + 1 %> - locale: en-UK - - <% end %> - <% end %> - <% end %> -<% end %> \ No newline at end of file diff --git a/test/fixtures/file_types.yml b/test/fixtures/file_types.yml deleted file mode 100644 index 2fbb4fb..0000000 --- a/test/fixtures/file_types.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#one: -# name: MyString -# icon_name: MyString -# icon_size: 1 -# icon_location: MyString -# -#two: -# name: MyString -# icon_name: MyString -# icon_size: 1 -# icon_location: MyString diff --git a/test/fixtures/file_uploads.yml b/test/fixtures/file_uploads.yml deleted file mode 100644 index 4499d51..0000000 --- a/test/fixtures/file_uploads.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#one: -# name: MyString -# title: MyString -# description: MyText -# size: 1 -# published: false -# location: MyString -# file_type_id: 1 -# -#two: -# name: MyString -# title: MyString -# description: MyText -# size: 1 -# published: false -# location: MyString -# file_type_id: 1 diff --git a/test/fixtures/guidance_groups.yml b/test/fixtures/guidance_groups.yml deleted file mode 100644 index 06003a8..0000000 --- a/test/fixtures/guidance_groups.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -dcc_guidance_group_1: - name: "DCC guidance group 1" - organisation: dcc - guidances: related_policies, existing_data, licensing_of_existing_data, relationship_to_existing_data, description_of_data_content, data_format, data_volumes, data_type, data_capture_methods, data_organisation, data_quality, documentation, metadata_capture, metadata_standards, discovery_by_users, ethical_issues, ipr_ownership_and_licencing, active_data_storage, backup_procedures, data_security, data_selection, preservation_plan, period_of_preservation, data_repository, audience, expected_reuse, method_for_data_sharing, timeframe_for_data_sharing, embargo_period, restrictions_on_sharing, managed_access_procedures, responsibilities, resourcing_skills_and_training, resourcing_hardware_and_software, resourcing_preservation_and_data_sharing - dmptemplates: dcc_template - -# funder groups -funder_guidance_group_1: - name: "Funder guidance group 1" - organisation: ahrc - guidances: ahrc_funder_guidance - dmptemplates: ahrc_template - -funder_guidance_group_2: - name: "Funder guidance group 2" - organisation: bbsrc - guidances: bbsrc_funder_guidance - dmptemplates: bbsrc_template - -# institution groups -institution_guidance_group_1: - name: "Anglia Ruskin University guidance group" - organisation: aru - guidances: aru_institution_guidance - dmptemplates: aru_template - -institution_guidance_group_2: - name: "Aston University guidance group" - organisation: au - guidances: au_institution_guidance_1, au_institution_guidance_2 - dmptemplates: au_template - -institution_guidance_group_3: - name: "Bangor University guidance group 1" - organisation: bu - guidances: bu_institution_guidance_1 - dmptemplates: bu_template - -institution_guidance_group_4: - name: "Bangor University guidance group 2" - organisation: bu - guidances: bu_institution_guidance_2 - dmptemplates: bu_template - -institution_guidance_group_5: - name: "institution child guidance group 1" - organisation: institution_child_one - -institution_guidance_group_6: - name: "institution child guidance group 2" - organisation: institution_child_one diff --git a/test/fixtures/guidances.yml b/test/fixtures/guidances.yml deleted file mode 100644 index 7aaac07..0000000 --- a/test/fixtures/guidances.yml +++ /dev/null @@ -1,176 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -related_policies: - text: "

    Questions to consider:

    • Are there any existing procedures that you will base your approach on?
    • Does your department/group have data management guidelines?
    • Does your institution have a data protection or security policy that you will follow?
    • Does your institution have a Research Data Management (RDM) policy?
    • Does your funder have a Research Data Management policy?
    • Are there any formal standards that you will adopt?

    Guidance:

    List any other relevant funder, institutional, departmental or group policies on data management, data sharing and data security. Some of the information you give in the remainder of the DMP will be determined by the content of other policies. If so, point/link to them here.

    " - themes: related_policies - -existing_data: - text: "

    Questions to consider:

    • Are there any existing data or methods that you can reuse?

    Guidance:

    Check to see if there are any existing data that you can reuse, for examples by consulting relevant repositories.

    When creating new data sources, explain why existing data sources cannot be re-used.

    A list of repositories is provided by Databib or Re3data .

    " - themes: existing_data - -licensing_of_existing_data: - text: "

    Questions to consider:

    • Do you need to pay to reuse existing data?
    • Are there any restrictions on the reuse of third-party data?
    • Can the data that you create - which may be derived from third-party data - be shared?

    Guidance:

    If purchasing or reusing existing data sources, explain how issues such as copyright and IPR have been addressed.

    " - themes: licensing_of_existing_data - -relationship_to_existing_data: - text: "

    Questions to consider:

    • What is the relationship to existing data e.g. in public repositories?
    • How does your data complement and integrate with existing data?

    Guidance:

    Consider the relationship between the data that you will capture and existing data available in public repositories or elsewhere.

    " - themes: relationship_to_existing_data - -description_of_data_content: - text: "

    Questions to consider:

    • What data will you create?

    Guidance:

    Give a brief description of the data that will be created, noting its content and coverage

    " - themes: description_of_data_content - -data_format: - text: "

    Questions to consider:

    • What format will your data be in?
    • Why have you chosen to use particular formats?
    • Do the chosen formats and software enable sharing and long-term validity of data?

    Guidance:

    Outline and justify your choice of format e.g. SPSS, Open Document Format, tab-delimited format, MS Excel.

    Decisions may be based on staff expertise, a preference for Open formats, the standards accepted by data centres or widespread usage with a given community. Using standardised and interchangeable or open lossless data formats ensures the long-term usability of data.

    See UKDA Guidance on recommended data formats.

    " - themes: data_format - -data_volumes: - text: "

    Questions to consider:

    • Do you have sufficient storage?
    • Do you need to include costs for additional managed storage?
    • Will the scale of the data pose challenges when sharing or transferring data between sites?

    Guidance:

    Consider the implications of data volumes in terms of storage, backup and access.

    Estimate the volume of data in KB/MB/GB and how this will grow to make sure any additional storage and technical support required can be provided.

    " - themes: data_volumes - -data_type: - text: "

    Questions to consider:

    • What types of data will you create?
    • Which types of data will have long-term value?

    Guidance:

    Outline the types of data that are expected to be produced from the project e.g. quantitative, qualitative, survey data, experimental measurements, models, images, audiovisual data, samples…

    Include the raw data arising directly from the research, the reduced data derived from it, and published data.

    " - themes: data_type - -data_capture_methods: - text: "

    Questions to consider:

    • How will the data be created?
    • What standards or methodologies will you use?

    Guidance:

    Outline how the data will be collected/generated and which community data standards (if any) will be used at this stage.

    " - themes: data_capture_methods - -data_organisation: - text: "

    Questions to consider:

    • How will you structure and name your folders and files?
    • How will you ensure that different versions of a dataset are easily identifiable?

    Guidance:

    Indicate how the data will be organised during the project, mentioning for example naming conventions, version control and folder structures. Consistent, well-ordered research data will be easier for the research team to find, understand and reuse.

    " - themes: data_organisation - -data_quality: - text: "

    Questions to consider:

    • How will you control data capture to ensure data quality?
    • What quality assurance processes will you adopt?

    Guidance:

    Explain how the consistency and quality of data collection will be controlled and documented.

    This may include processes such as calibration, repeat samples or measurements, standardised data capture or recording, data entry validation, peer review of data or representation with controlled vocabularies.

    " - themes: data_quality - -documentation: - text: "

    Questions to consider:

    • What metadata, documentation or other supporting material should accompany the data for it to be interpreted correctly?
    • What information needs to be retained to enable the data to be read and interpreted in the future?

    Guidance:

    Describe the types of documentation that will accompany the data to provide a secondary users with any necessary details to prevent misuse, misinterpretation or confusion. This may include information on the methodology used to collect the data, analytical and procedural information, definitions of variables, units of measurement, any assumptions made, the format and file type of the data.

    " - themes: documentation - -metadata_capture: - text: "

    Questions to consider:

    • How will you capture / create the metadata?
    • Can any of this information be created automatically?

    Guidance:

    Metadata should be created to describe the data and aid discovery. Consider how you will capture this information and where it will be recorded e.g. in a database with links to each item, in a ‘readme’ text file, in file headers.

    " - themes: metadata_capture - -metadata_standards: - text: "

    Questions to consider:

    • What metadata standards will you use and why?

    Guidance:

    Researchers are strongly encouraged to utilise community standards to describe and structure data, where these are in place. The DCC offers a catalogue of disciplinary metadata standards.

    " - themes: metadata_standards - -discovery_by_users: - text: "

    Questions to consider:

    • How will potential users find out about your data?
    • Will you provide metadata online to aid discovery and reuse?

    Guidance:

    Indicate how potential new users can find out about your data and identify whether they could be suitable for their research purposes. For example, you may provide basic discovery metadata online, such as title, author, subjects, keywords and publisher.

    " - themes: discovery_by_users - -ethical_issues: - text: "

    Questions to consider:

    • Have you gained consent for data preservation and sharing?
    • How will sensitive data be handled to ensure it is stored and transferred securely?
    • How will you protect the identity of participants? e.g. via anonymisation or using managed access procedures?

    Guidance:

    Investigators carrying out research involving human participants must ensure that consent is obtained to share data. Managing ethical concerns may include: anonymisation of data; referral to departmental or institutional ethics committees; and formal consent agreements. Ethical issues may affect how you store data, who can see/use it and how long it is kept. You should show that you’re aware of this and have planned accordingly.

    See UKDA Guidance on Consent, Confidentiality and Ethics.

    " - themes: ethical_issues - -ipr_ownership_and_licencing: - text: "

    Questions to consider:

    • Who owns the data?
    • How will the data be licensed for reuse?
    • Will data sharing be postponed / restricted e.g. to seek patents?

    Guidance:

    State who will own the copyright and IPR of any new data that you will generate. For multi-partner projects, IPR ownership may be worth covering in a consortium agreement. Outline any restrictions needed on data sharing e.g. to protect proprietary or patentable data.

    See DCC How to license research data.

    " - themes: ipr_ownership_and_licencing - -active_data_storage: - text: "

    Questions to consider:

    • Where will the data be stored?
    • Do you have access to enough storage or will you need to include charges for additional services?

    Guidance:

    Storing data on laptops, computer hard drives or external storage devices alone is very risky. The use of robust, managed storage provided by university IT teams is preferable.

    See UKDA Guidance on Data Storage.

    " - themes: active_data_storage - -backup_procedures: - text: "

    Questions to consider:

    • How will the data be backed up? i.e. how often, to where, how many copies, is this automated…
    • Who will be responsible for backup?
    • Have you tested whether you can restore from your backups?

    Guidance:

    Describe the data back-up procedures that you will adopt to ensure the data and metadata are securely stored during the lifetime of the project. You may need to discuss your institution’s policy on back-ups. It is better to use automatic backup services provided by university IT than rely on manual processes.

    See UKDA Guidance on Data Backup.

    " - themes: backup_procedures - -data_security: - text: "

    Questions to consider:

    • What are the risks to data security and how will these be managed?
    • Will you follow any formal standards?

    Guidance:

    If your data is sensitive (e.g. detailed personal data, politically sensitive information or trade secrets) you should discuss any appropriate security measures that you will be taking. Note the main risks and how these will be managed. Identify any formal standards that you will comply with e.g. ISO 27001.

    See DCC Briefing Paper on Information Security Management - ISO 27000.

    See UKDA Guidance on Data Security.

    " - themes: data_security - -data_selection: - text: "

    Questions to consider:

    • Which data are of long-term value and should be shared and/or preserved?
    • How will you decide what to keep?

    Guidance:

    Indicate which data you intend to preserve beyond the period of funding. This should be based on what has long-term value and is economically viable to keep. Consider how long you wish to keep the data and what will happen to it e.g. deposit in a data repository to enable reuse.

    See DCC How to appraise and select research data.

    " - themes: data_selection - -preservation_plan: - text: "

    Questions to consider:

    • What is the long-term preservation plan for the dataset? e.g. deposit in a data repository
    • Will additional resources be needed to prepare data for deposit or meet charges from data repositories?

    Guidance:

    Researchers should consider how datasets that have long-term value will be preserved and curated beyond the lifetime of the grant. Also outline the plans for preparing and documenting data for sharing and archiving.

    If you do not propose to use an established repository, the data management plan should demonstrate that resources and systems will be in place to enable the data to be curated effectively beyond the lifetime of the grant.

    " - themes: preservation_plan - -period_of_preservation: - text: "

    Questions to consider:

    • How long will the data be retained and preserved?

    Guidance:

    This may depend on the type of data. Most research funders expect data to be retained for a minimum of 10 years from the end of the project. For data that by their nature cannot be re-measured, efforts should be made to retain them indefinitely.

    " - themes: period_of_preservation - -data_repository: - text: "

    Questions to consider:

    • Where (i.e. in which repository) will the data be deposited?

    Guidance:

    Most research funders recommend the use of established data repositories, community databases and related initiatives to aid data preservation, sharing and reuse.

    An international list of data repositories is available via Databib or Re3data.

    " - themes: data_repository - -audience: - text: "

    Questions to consider:

    • Who may be interested in using your data?

    Guidance:

    Where possible outline the types of users you expect and estimate numbers.

    " - themes: audiencethe - -expected_reuse: - text: "

    Questions to consider:

    • What are the further intended or foreseeable research uses for the data?

    Guidance:

    You should think about the possibilities for re-use of your data in other contexts and by other users, and connect this as appropriate with your plans for dissemination and Pathways to Impact. Where there is potential for reuse, you should use standards and formats that facilitate this.

    " - themes: expected_reuse - -method_for_data_sharing: - text: "

    Questions to consider:

    • How will you make the data available to others?
    • With whom will you share the data, and under what conditions?

    Guidance:

    Consider where, how, and to whom the data should be made available. Will you share data via a data repository, handle data requests directly or use another mechanism?

    The methods used to share data will be dependent on a number of factors such as the type, size, complexity and sensitivity of data. Mention earlier examples to show a track record of effective data sharing.

    " - themes: method_for_data_sharing - -timeframe_for_data_sharing: - text: "

    Questions to consider:

    • When will you make the data available?

    Guidance:

    Data (with accompanying metadata) should be shared in a timely fashion. It is generally expected that timely release would generally be no later than the release through publication of the main findings and should be in-line with established best practice in the field.

    " - themes: timeframe_for_data_sharing - -embargo_period: - text: "

    Questions to consider:

    • For how long do you need exclusive use of the data and why?

    Guidance:

    The value of data often depends on timeliness. Researchers have a legitimate interest in benefiting from their investment of time and effort in producing data, but not in prolonged exclusive use. Research funders typically allow embargoes in line with practice in the field, but expect these to be outlined and justified.

    " - themes: embargo_period - -restrictions_on_sharing: - text: "

    Questions to consider:

    • Are any restrictions on data sharing required? e.g. limits on who can use the data, when and for what purpose.
    • What restrictions are needed and why?
    • What action will you take to overcome or minimise restrictions?

    Guidance:

    Outline any expected difficulties in data sharing, along with causes and possible measures to overcome these. Restrictions to data sharing may be due to participant confidentiality, consent agreements or IPR. Strategies to limit restrictions may include: anonymising or aggregating data; gaining participant consent for data sharing; gaining copyright permissions; and agreeing a limited embargo period.

    " - themes: restrictions_on_sharing - -managed_access_procedures: - text: "

    Questions to consider:

    • Will access be tightly controlled or restricted? e.g. by using data enclaves / secure data services
    • Will a data sharing agreement be required?
    • How will the data be licensed for reuse?

    Guidance:

    Indicate whether external users are (will be) bound by data sharing agreements, licenses or end-user agreements. If so, set out the terms and key responsibilities to be followed.

    Note how access will be controlled, for example by the use of specialist services. A data enclave provides a controlled secure environments in which eligible researchers can perform analyses using restricted data resources.

    Where a managed access process is required, the procedure should be clearly described and transparent.

    " - themes: managed_access_procedures - -responsibilities: - text: "

    Questions to consider:

    • Who is responsible for each data management activity?
    • How are responsibilities split across partner sites in collaborative research projects?

    Guidance:

    Outline the roles and responsibilities for all activities e.g. data capture, metadata production, data quality, storage and backup, data archiving & data sharing. Individuals should be named where possible. For collaborative projects you should explain the co-ordination of data management responsibilities across partners.

    See UKDA Guidance on data management roles and responsibilities.

    " - themes: responsibilities - -resourcing_skills_and_training: - text: "

    Questions to consider:

    • Is additional specialist expertise (or training for existing staff) required?
    • How will additional skills be sourced?

    Guidance:

    Carefully consider any resources needed to deliver the plan. Where dedicated resources are needed, these should be outlined and justified.

    Outline any relevant technical expertise, support and training that is likely to be required and how it will be acquired.

    " - themes: resourcing_skills_and_training - -resourcing_hardware_and_software: - text: "

    Questions to consider:

    • Are there appropriate computational facilities to manage, store and analyse the data?

    Guidance:

    Carefully consider any resources needed to deliver the plan. Where dedicated resources are needed, these should be outlined and justified.

    Provide details and justification for any hardware or software which will be used to support the project’s research methodology, which is additional or exceptional to conventional desk-based research and institutional provision. This includes additional storage and backup costs that may be charged by IT services.

    " - themes: resourcing_hardware_and_software - -resourcing_preservation_and_data_sharing: - text: "

    Questions to consider:

    • Will charges be applied by data repositories?
    • Have you costed in time and effort to prepare the data for sharing / preservation?

    Guidance:

    Carefully consider any resources needed to deliver the plan. Where dedicated resources are needed, these should be outlined and justified.

    Funding should be included to cover any charges applied by data repositories, for example to handle data of exceptional size or complexity. Also remember to cost in time and effort to prepare data for deposit and ensure it is adequately documented to enable reuse.

    If you are not depositing in a data repository, ensure you have appropriate resources and systems in place to share and preserve the data.

    See UKDA How to cost data management.

    " - themes: resourcing_preservation_and_data_sharing - -ahrc_funder_guidance: - text: "sample funder guidance ahrc" - themes: embargo_period - -bbsrc_funder_guidance: - text: "sample funder guidance bbsrc" - themes: embargo_period - -aru_institution_guidance: - text: "sample institution guidance aru" - themes: embargo_period - -au_institution_guidance_1: - text: "sample institution guidance au 1" - themes: embargo_period - -au_institution_guidance_2: - text: "sample instiution guidance au 2" - themes: embargo_period - -bu_institution_guidance_1: - text: "sample institution guidance bu 1" - themes: embargo_period - -bu_institution_guidance_2: - text: "sample institution guidance bu 2" - themes: embargo_period - -one: - text: "one" - themes: embargo_period - - - diff --git a/test/fixtures/languages.yml b/test/fixtures/languages.yml deleted file mode 100644 index 55ea794..0000000 --- a/test/fixtures/languages.yml +++ /dev/null @@ -1,17 +0,0 @@ -en-UK: - abbreviation: 'en-UK' - description: 'UK English' - name: 'English (UK)' - default_language: true - -en-US: - abbreviation: 'en-US' - description: 'US English' - name: 'English (US)' - default_language: false - -fr: - abbreviation: 'fr' - description: 'French' - name: 'French' - default_language: false \ No newline at end of file diff --git a/test/fixtures/option_warnings.yml b/test/fixtures/option_warnings.yml deleted file mode 100644 index 46bac23..0000000 --- a/test/fixtures/option_warnings.yml +++ /dev/null @@ -1,40 +0,0 @@ -single_select_1_warning: - option: single_select_1 - organisation: uog - text: This warning should display when option 1 of the single item select box example is selected for a project at the University of Glasgow - -single_select_2_warning: - option: single_select_2 - organisation: hatii - text: This warning should display when option 2 of the single item select box example is selected for a project at HATII - - -multiple_select_3_warning: - option: multiple_select_3 - organisation: uoe - text: This warning should display when option 3 of the multiple item select box example is selected for a project at the University of Edinburgh - -multiple_select_4_warning: - option: multiple_select_4 - organisation: uoe_si - text: This warning should display when option 4 of the multiple item select box example is selected for a project at the School of Informatics - -radio_button_1_warning: - option: radio_button_1 - organisation: uog - text: This warning should display when option 1 of the radio button example is selected for a project at the University of Glasgow - -radio_button_2_warning: - option: radio_button_2 - organisation: hatii - text: This warning should display when option 2 of the radio button example is selected for a project at HATII - -checkbox_3_warning: - option: checkbox_3 - organisation: uoe - text: This warning should display when option 3 of the checkbox example is selected for a project at the University of Edinburgh - -checkbox_4_warning: - option: checkbox_4 - organisation: uoe_si - text: This warning should display when option 4 of the checkbox example is selected for a project at the School of Informatics \ No newline at end of file diff --git a/test/fixtures/options.yml b/test/fixtures/options.yml deleted file mode 100644 index e54b8d9..0000000 --- a/test/fixtures/options.yml +++ /dev/null @@ -1,89 +0,0 @@ -single_select_1: - question: single_select_box - text: Option 1 - number: 1 - -single_select_2: - question: single_select_box - text: Option 2 - number: 2 - -single_select_3: - question: single_select_box - text: Option 3 - number: 3 - -single_select_4: - question: single_select_box - text: Option 4 - number: 4 - -multiple_select_1: - question: multiple_select_box - text: Option 1 - number: 1 - -multiple_select_2: - question: multiple_select_box - text: Option 2 - number: 2 - -multiple_select_3: - question: multiple_select_box - text: Option 3 - number: 3 - -multiple_select_4: - question: multiple_select_box - text: Option 4 - number: 4 - -radio_button_1: - question: radio_button - text: Option 1 - number: 1 - -radio_button_2: - question: radio_button - text: Option 2 - number: 2 - -radio_button_3: - question: radio_button - text: Option 3 - number: 3 - -radio_button_4: - question: radio_button - text: Option 4 - number: 4 - -checkbox_1: - question: checkbox - text: Option 1 - number: 1 - -checkbox_2: - question: checkbox - text: Option 2 - number: 2 - -checkbox_3: - question: checkbox - text: Option 3 - number: 3 - -checkbox_4: - question: checkbox - text: Option 4 - number: 4 - -mrc_5_2_yes: - question: mrc_5_2 - text: "Yes" - number: 1 - -mrc_5_2_no: - question: mrc_5_2 - text: "No" - number: 2 \ No newline at end of file diff --git a/test/fixtures/org_token_permissions.yml b/test/fixtures/org_token_permissions.yml deleted file mode 100644 index a4748f5..0000000 --- a/test/fixtures/org_token_permissions.yml +++ /dev/null @@ -1,15 +0,0 @@ -dcc_one: - token_permission_type: plans_token_type - organisation: dcc - -dcc_two: - token_permission_type: guidances_token_type - organisation: dcc - -aru_one: - token_permission_type: plans_token_type - organisation: aru - -au_one: - token_permission_type: guidances_token_type - organisation: au \ No newline at end of file diff --git a/test/fixtures/organisation_types.yml b/test/fixtures/organisation_types.yml deleted file mode 100644 index c969384..0000000 --- a/test/fixtures/organisation_types.yml +++ /dev/null @@ -1,5 +0,0 @@ -<% # Load the org types from thosedefined in the MagicStrings section of the locale %> -<% I18n.t("magic_strings.organisation_types").each do |k,v| %> -<%= k %>: - name: <%= "#{v}" %> -<% end %> \ No newline at end of file diff --git a/test/fixtures/organisations.yml b/test/fixtures/organisations.yml deleted file mode 100644 index df643f5..0000000 --- a/test/fixtures/organisations.yml +++ /dev/null @@ -1,57 +0,0 @@ -# Produces: -# ----------------------------- -# curation_center -# funder -# complete <-- child of curation_center -# -# institution_[1..2] -# school_[1..2] -# project_[1..2] - -# Import organisation_types.yml so that we can dynamically generate organisations -<% organisation_types = YAML::load(ERB.new(File.read('./test/fixtures/organisation_types.yml')).result) %> - -curation_center: - name: 'Curation Centre' - abbreviation: 'cc' - organisation_type: organisation - contact_email: 'admin@example-curation-centre.org' - -funder: - name: 'Grant Funder' - abbreviation: 'funder' - organisation_type: funder - contact_email: 'admin@example-funder.org' - -# We unfortunatley cannot tab this out nicely because YAML is expecting the values in -# the first column -<% organisation_types.each do |lbl, obj| %> - <% unless ['funder', 'organisation'].include?(lbl) %> - <% 2.times do |n| %> - -<%= lbl %>_<%= n + 1 %>: - name: <%= "#{obj['name']} #{n}" %> - domain: <%= "www.#{lbl}-#{n + 1}.org" %> - organisation_type: <%= "#{lbl}" %> - contact_email: "admin@example-#{lbl}-#{n + 1}.org" - - <% end %> - <% end %> -<% end %> - -complete: - name: 'Organisation with all attributes' - abbreviation: 'complete' - target_url: 'http:\/\/www.complete-org.org' - organisation_type: organisation - domain: 'www.complete-org.org' - wayfless_entity: '' - stylesheet_file_id: 'complete-org.css' - is_other: false - sort_name: 'complete' - banner_text: 'Complete organisation banner text' - region_id: eu - language_id: en-UK - logo_uid: '2016/08/30/1234abcd-complete-org.gif' - logo_name: 'complete-org.gif' - contact_email: 'admin@example-complete-org.org' \ No newline at end of file diff --git a/test/fixtures/phases.yml b/test/fixtures/phases.yml deleted file mode 100644 index 1a24240..0000000 --- a/test/fixtures/phases.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Produces: -# ----------------------------- -# Generates 1 Phase for each published template and 2 Phases for each one that -# is unpublished (see dmptemplates.yml for template list) -# -# [template]_phase_1 -# [template]_unpublished_phase_[1..2] -# -# - -# Import dmptemplates.yml so that we can dynamically generate phases -<% templates = YAML::load(ERB.new(File.read('./test/fixtures/dmptemplates.yml')).result) %> - -<% templates.each do |lbl, hash| %> - -<%= lbl %>_phase_1: - title: <%= "hash['title'] - Phase 1" %> - number: 1 - dmptemplate: <%= lbl %> - - <% if lbl.include?('_unpublished') %> -<%= lbl %>_phase_2: - title: <%= "hash['title'] - Phase 2" %> - number: 2 - dmptemplate: <%= lbl %> - <% end %> - -<% end %> diff --git a/test/fixtures/plan_sections.yml b/test/fixtures/plan_sections.yml deleted file mode 100644 index b5a70f5..0000000 --- a/test/fixtures/plan_sections.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#one: -# edit: false -# at: 2013-06-11 15:17:04 -# user_editing_id: 1 -# section_id: 1 -# plan_id: 1 -# -#two: -# edit: false -# at: 2013-06-11 15:17:04 -# user_editing_id: 1 -# section_id: 1 -# plan_id: 1 diff --git a/test/fixtures/plans.yml b/test/fixtures/plans.yml deleted file mode 100644 index 6b64ebd..0000000 --- a/test/fixtures/plans.yml +++ /dev/null @@ -1,11 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#one: -# locked: false -# project_id: 1 -# version_id: 1 -# -#two: -# locked: false -# project_id: 1 -# version_id: 1 diff --git a/test/fixtures/project_groups.yml b/test/fixtures/project_groups.yml deleted file mode 100644 index d0dd7b2..0000000 --- a/test/fixtures/project_groups.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#one: -# project_creator: false -# project_editor: false -# user_id: 1 -# project_id: 1 -# -#two: -# project_creator: false -# project_editor: false -# user_id: 1 -# project_id: 1 - -<% 4.times do |n| %> - many_projects_group_<%= n + 1 %>: - project_creator: true - project_editor: true - user: with_many_projects - project: test_plan<%= "_#{n + 1}" if n > 0 %> -<% end %> diff --git a/test/fixtures/projects.yml b/test/fixtures/projects.yml deleted file mode 100644 index 5218482..0000000 --- a/test/fixtures/projects.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html -#two: -# title: MyString -# note: MyText -# locked: false -# dmptemplate_id: 1 - -test_plan: - title: "AHRC Template project" - dmptemplate: ahrc_template - organisation: ahrc - -test_plan_2: - title: "AHRC Template second project" - dmptemplate: ahrc_template_2 - organisation: ahrc - -test_plan_3: - title: "DCC Template project" - dmptemplate: dcc_template - organisation: dcc - -test_plan_4: - title: "DMP Template project" - dmptemplate: dmp_template - organisation: dcc \ No newline at end of file diff --git a/test/fixtures/questions.yml b/test/fixtures/questions.yml deleted file mode 100644 index a730517..0000000 --- a/test/fixtures/questions.yml +++ /dev/null @@ -1,746 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -#Administrative Data - -related_policies: - text: "Related Policies:" - guidance: "

    Questions to consider:

    • Are there any existing procedures that you will base your approach on?
    • Does your department/group have data management guidelines?
    • Does your institution have a data protection or security policy that you will follow? - Does your institution have a Research Data Management (RDM) policy?
    • Does your funder have a Research Data Management policy?
    • Are there any formal standards that you will adopt?

    Guidance:

    List any other relevant funder, institutional, departmental or group policies on data management, data sharing and data security. Some of the information you give in the remainder of the DMP will be determined by the content of other policies. If so, point/link to them here.

    " - number: 1 - section: administrative_data - themes: related_policies - -#Data Collection - -what_data_will_you_collect_or_create: - text: What data will you collect or create? - guidance: "

    Questions to consider:

    • What type, format and volume of data?
    • Do your chosen formats and software enable sharing and long-term access to the data?
    • Are there any existing data that you can reuse?

    Guidance:

    Give a brief description of the data, including any existing data or third-party sources that will be used, in each case noting its content, type and coverage. Outline and justify your choice of format and consider the implications of data format and data volumes in terms of storage, backup and access.

    " - number: 1 - section: data_collection - themes: data_format, data_volumes, data_type, existing_data, description_of_data_content - -how_will_the_data_be_collected_or_created: - text: How will the data be collected or created? - guidance: "

    Questions to consider:

    • What standards or methodologies will you use?
    • How will you structure and name your folders and files?
    • How will you handle versioning?
    • What quality assurance processes will you adopt?

    Guidance:

    Outline how the data will be collected/created and which community data standards (if any) will be used. Consider how the data will be organised during the project, mentioning for example naming conventions, version control and folder structures. Explain how the consistency and quality of data collection will be controlled and documented. This may include processes such as calibration, repeat samples or measurements, standardised data capture or recording, data entry validation, peer review of data or representation with controlled vocabularies.

    " - number: 2 - section: data_collection - themes: data_capture_methods, data_quality - -#Documentation and Metadata - -what_documentation_and_metadata_will_acompany_the_data: - text: What documentation and metadata will acompany the data? - guidance: "

    Questions to consider:

    • What information is needed for the data to be to be read and interpreted in the future?
    • How will you capture / create this documentation and metadata?
    • What metadata standards will you use and why?

    Guidance:

    Describe the types of documentation that will accompany the data to help secondary users to understand and reuse it. This should at least include basic details that will help people to find the data, including who created or contributed to the data, its title, date of creation and under what conditions it can be accessed.

    Documentation may also include details on the methodology used, analytical and procedural information, definitions of variables, vocabularies, units of measurement, any assumptions made, and the format and file type of the data. Consider how you will capture this information and where it will be recorded. Wherever possible you should identify and use existing community standards.

    " - number: 1 - section: documentation_and_metadata - themes: metadata_capture, documentation, metadata_standards - -#Ethics and Legal Compliance - -how_will_you_manage_any_ethical_issues: - text: How will you manage any ethical issues? - guidance: "

    Questions to consider:

    • Have you gained consent for data preservation and sharing?
    • How will you protect the identity of participants if required? e.g. via anonymisation
    • How will sensitive data be handled to ensure it is stored and transferred securely?

    Guidance:

    Ethical issues affect how you store data, who can see/use it and how long it is kept. Managing ethical concerns may include: anonymisation of data; referral to departmental or institutional ethics committees; and formal consent agreements. You should show that you are aware of any issues and have planned accordingly. If you are carrying out research involving human participants, you must also ensure that consent is requested to allow data to be shared and reused.

    " - number: 1 - section: ethics_and_legal_compliance - themes: ethical_issues, data_security - -how_will_you_manage_copyright_and_intellectual_property_rights_ipr_issues: - text: How will you manage copyright and Intellectual Property Rights (IPR) issues? - guidance: "

    Questions to consider:

    • Who owns the data?
    • How will the data be licensed for reuse?
    • Are there any restrictions on the reuse of third-party data?
    • Will data sharing be postponed / restricted e.g. to publish or seek patents?

    Guidance:

    State who will own the copyright and IPR of any data that you will collect or create, along with the licence(s) for its use and reuse. For multi-partner projects, IPR ownership may be worth covering in a consortium agreement. Consider any relevant funder, institutional, departmental or group policies on copyright or IPR. Also consider permissions to reuse third-party data and any restrictions needed on data sharing.

    " - number: 2 - section: ethics_and_legal_compliance - themes: licensing_of_existing_data, ipr_ownership_and_licencing - -#Storage and Backup - -how_will_the_data_be_stored_and_backed_up_during_the_research: - text: How will the data be stored and backed up during the research? - guidance: "

    Questions to consider:

    • Do you have sufficient storage or will you need to include charges for additional services?
    • How will the data be backed up?
    • Who will be responsible for backup and recovery?
    • How will the data be recovered in the event of an incident?

    Guidance:

    State how often the data will be backed up and to which locations. How many copies are being made? Storing data on laptops, computer hard drives or external storage devices alone is very risky. The use of robust, managed storage provided by university IT teams is preferable. Similarly, it is normally better to use automatic backup services provided by IT Services than rely on manual processes. If you choose to use a third-party service, you should ensure that this does not conflict with any funder, institutional, departmental or group policies, for example in terms of the legal jurisdiction in which data are held or the protection of sensitive data.

    " - number: 1 - section: storage_and_backup - themes: active_data_storage, backup_procedures - -how_will_you_manage_access_and_security: - text: How will you manage access and security? - guidance: "

    Questions to consider:

    • What are the risks to data security and how will these be managed?
    • How will you control access to keep the data secure?
    • How will you ensure that collaborators can access your data securely?
    • If creating or collecting data in the field how will you ensure its safe transfer into your main secured systems?

    Guidance:

    If your data is confidential (e.g. personal data not already in the public domain, confidential information or trade secrets), you should outline any appropriate security measures and note any formal standards that you will comply with e.g. ISO 27001."

    " - number: 2 - section: storage_and_backup - themes: data_security, managed_access_procedures - -#Selection and Preservation - -which_data_are_of_long-term_value_and_should_be_retained_shared_and-or_preserved: - text: Which data are of long-term value and should be retained, shared, and/or preserved? - guidance: "

    Questions to consider:

    • What data must be retained/destroyed for contractual, legal, or regulatory purposes?
    • How will you decide what other data to keep?
    • What are the foreseeable research uses for the data?
    • How long will the data be retained and preserved?

    Guidance:

    Consider how the data may be reused e.g. to validate your research findings, conduct new studies, or for teaching. Decide which data to keep and for how long. This could be based on any obligations to retain certain data, the potential reuse value, what is economically viable to keep, and any additional effort required to prepare the data for data sharing and preservation. Remember to consider any additional effort required to prepare the data for sharing and preservation, such as changing file formats.

    " - number: 1 - section: selection_and_preservation - themes: data_selection - -what_is_the_long-term_preservation_plan_for_the_dataset: - text: What is the long-term preservation plan for the dataset? - guidance: "

    Questions to consider:

    • Where e.g. in which repository or archive will the data be held?
    • What costs if any will your selected data repository or archive charge?
    • Have you costed in time and effort to prepare the data for sharing / preservation?

    Guidance:

    Consider how datasets that have long-term value will be preserved and curated beyond the lifetime of the grant. Also outline the plans for preparing and documenting data for sharing and archiving. If you do not propose to use an established repository, the data management plan should demonstrate that resources and systems will be in place to enable the data to be curated effectively beyond the lifetime of the grant.

    " - number: 2 - section: selection_and_preservation - themes: preservation_plan - -#Data Sharing - -how_will_you_share_the_data: - text: How will you share the data? - guidance: "

    Questions to consider:

    • How will potential users find out about your data?
    • With whom will you share the data, and under what conditions?
    • Will you share data via a repository, handle requests directly or use another mechanism?
    • When will you make the data available?
    • Will you pursue getting a persistent identifier for your data?

    Guidance:

    Consider where, how, and to whom data with acknowledged long-term value should be made available. The methods used to share data will be dependent on a number of factors such as the type, size, complexity and sensitivity of data. If possible, mention earlier examples to show a track record of effective data sharing. Consider how people might acknowledge the reuse of your data.

    " - number: 1 - section: data_sharing - themes: method_for_data_sharing - -are_any_restrictions_on_data_sharing_required: - text: Are any restrictions on data sharing required? - guidance: "

    Questions to consider:

    • What action will you take to overcome or minimise restrictions?
    • For how long do you need exclusive use of the data and why?
    • Will a data sharing agreement (or equivalent) be required?

    Guidance:

    Outline any expected difficulties in sharing data with acknowledged long-term value, along with causes and possible measures to overcome these. Restrictions may be due to confidentiality, lack of consent agreements or IPR, for example. Consider whether a non-disclosure agreement would give sufficient protection for confidential data.

    " - number: 2 - section: data_sharing - themes: restrictions_on_sharing, embargo_period - -#Responsibilities and Resources - -who_will_be_responsible_for_data_management: - text: Who will be responsible for data management? - guidance: "

    Questions to consider:

    • Who is responsible for implementing the DMP, and ensuring it is reviewed and revised?
    • Who will be responsible for each data management activity?
    • How will responsibilities be split across partner sites in collaborative research projects?
    • Will data ownership and responsibilities for RDM be part of any consortium agreement or contract agreed between partners?

    Guidance:

    Outline the roles and responsibilities for all activities e.g. data capture, metadata production, data quality, storage and backup, data archiving & data sharing. Consider who will be responsible for ensuring relevant policies will be respected. Individuals should be named where possible.

    " - number: 1 - section: responsibilities_and_resources - themes: responsibilities - -what_resources_will_you_require_to_deliver_your_plan: - text: What resources will you require to deliver your plan? - guidance: "

    Questions to consider:

    • Is additional specialist expertise (or training for existing staff) required?
    • Do you require hardware or software which is additional or exceptional to existing institutional provision?
    • Will charges be applied by data repositories?

    Guidance:

    Carefully consider any resources needed to deliver the plan, e.g. software, hardware, technical expertise, etc. Where dedicated resources are needed, these should be outlined and justified.

    " - number: 2 - section: responsibilities_and_resources - themes: resourcing_skills_and_training, resourcing_hardware_and_software, resourcing_preservation_and_data_sharing - -#Multiple Choice - -#single_select_box: -# text: Example select box limited to one option -# number: 1 -# section: multiple_choice -# -#multiple_select_box: -# text: Example select box allowing multiple options -# number: 2 -# section: multiple_choice -# -#radio_button: -# text: Example radio button -# number: 3 -# section: multiple_choice -# -#checkbox: -# text: Example checkbox -# number: 4 -# section: multiple_choice - -ahrc_1_1: - text: Summary of Digital Outputs and Digital Technologies - guidance: "

    You should provide a brief and clear description of the digital output or digital technology being proposed, considering the following aspects: purpose, source data, content, functionality, use and its relationship to the research questions. You should identify the type of access envisaged, if applicable, such as 'freely available online'.

    The summary should provide clear overview of what you intend to achieve technically, to enable reviewers to assess whether the plans for achieving this are appropriate. You should provide a level of detail which is appropriate to the digital output or digital technology being proposed and its cost and status within the project.

    " - number: 1 - section: ahrc_1 - themes: description_of_data_content, method_for_data_sharing - -ahrc_2_1: - text: "Technical Methodology: Standards and Formats" - guidance: "

    You should provide information about your choice of data and file formats. You must provide any relevant vital statistics relating to the data, such as size, quantity and duration. Although such statistics might need to rely on estimation, you should provide the reasoning behind your calculations. You should give your reasons for using the standards or formats chosen.

    " - number: 1 - section: ahrc_2 - themes: data_format, data_volumes, data_type - -ahrc_2_2: - text: "Technical Methodology: Hardware and Software" - guidance: "

    You should provide information about and the rationale for any hardware or software which will be used to support the project’s research methodology, which is additional or exceptional to conventional desk-based research and institutional provision. They should be included in the Justification of Resources and cross-referenced if there is an associated budget line. Where necessary you should produce additional justification of the use of such items.

    You must write ‘Not applicable’ if this section is not relevant to the type of digital output or digital technology proposed.

    " - number: 2 - section: ahrc_2 - themes: resourcing_hardware_and_software - -ahrc_2_3: - text: "Technical Methodology Data Acquisition, Processing, Analysis and Use" - guidance: "

    You should provide information about the process of technical development, showing how the standards and formats described in section 2.a and the hardware and software described in section 2.b relate to each other. You must show that you have considered how you will achieve your digital output or digital technology in practice, including issues of timetabling.

    You should consider the technical development process from the point of data capture or data creation through to final delivery (in the case of a digital output) or analysis (in the case of a digital process). You should consider issues such as backup, monitoring, quality control and internal documentation where relevant, identifying procedures which are appropriate to the research environments. For example Technical Reviewers acknowledge that the backup procedures which are possible during fieldwork might be very different to those which are possible within an office environments.

    This section needs to relate to the timetable and milestones given in the Case for Support as well as the project’s overall research methodology. The Technical Reviewer will be assessing the alignment of the technical development process with other project activities for logic and timeliness.

    " - number: 3 - section: ahrc_2 - themes: data_capture_methods, data_quality, data_organisation, documentation, metadata_capture, metadata_standards, backup_procedures - -ahrc_3_1: - text: "Technical Support and Relevant Experience" - guidance: "" - number: 1 - section: ahrc_3 - themes: resourcing_skills_and_training, responsibilities - -ahrc_4_1: - text: "Preserving Your Data" - guidance: "

    Preservation of digital outputs is necessary in order for them to endure changes in the technological environments and remain potentially re-usable in the future. In this section you must state what, if any, digital outputs of your project you intend to preserve beyond the period of funding.

    The length and cost of preservation should be proportionate to the value and significance of the digital outputs. If you believe that none of these should be preserved this must be justified, and if the case is a good one the application will not be prejudiced.

    You must consider preservation in four ways: what, where, how and for how long. You must also consider any institutional support needed in order to carry out these plans, whether from an individual, facility, organisation or service.

    You should think about the possibilities for re-use of your data in other contexts and by other users, and connect this as appropriate with your plans for dissemination and Pathways to Impact.Where there is potential for re-usability, you should use standards and formats that facilitate this.

    The Technical Reviewer will be looking for evidence that you understand the reasons for the choice of technical standards and formats described in Section 2.a Technical Methodology: Standards and Formats.

    You should describe the types of documentation which will accompany the data. Documentation in this sense means technical documentation as well as user documentation. It includes, for instance, technical description, code commenting, project-build guidelines, the documentation of technical decisions and resource metadata which is additional to the standards which you have described in Section 2.a. Not all types of documentation will be relevant to a project and the quantity of documentation proposed should be proportionate to the envisaged value of the data.

    " - number: 1 - section: ahrc_4 - themes: preservation_plan, period_of_preservation, resourcing_preservation_and_data_sharing, documentation - -ahrc_4_2: - text: "Ensuring Continued Accessibility and Use of Your Digital Outputs" - guidance: "

    In this section you must provide information about any plans for ensuring that digital outputs remain sustainable in the sense of immediately accessible and usable beyond the period of funding. There are costs to ensuring sustainability in this sense over and above the costs of preservation. The project's sustainability plan should therefore be proportionate to the envisaged longer-term value of the data for the research community and should be closely related to your plans for dissemination and Pathways to Impact.

    If you believe that digital outputs should not be sustained beyond the period of funding then this should be justified. It is not mandatory to sustain all digital outputs. While you should consider the long-term value of the digital outputs to the research community, where they are purely ancillary to a project’s research outputs there may not be a case for sustaining them (though there would usually be a case for preservation).

    You must consider the sustainability of your digital outputs in five ways: what, where, how, for how long, and how the cost will be covered. You must make appropriate provision for user consultation and user testing in this connection, and plan the development of suitable user documentation.

    You should provide justification if you do not envisage open, public access. A case can be made for charging for or otherwise limiting access, but the default expectation is that access will be open. The Technical Reviewer will be looking for realistic commitments to sustaining public access in line with affordability and the longer-term value of the digital output.

    You must consider any institutional support needed in order to carry out these plans, if not covered under Section 3, as well as the cost of keeping the digital output publicly available in the future, including issues relating to maintenance, infrastructure and upgrade (such as the need to modify aspects of a web interface or software application in order to account for changes in the technological environments). In order to minimise sustainability costs, it is generally useful that the expertise involved in the development of your project is supported by expertise in your own or a partner institution.

    A sustainability plan does not necessarily mean a requirement to generate income or prevent resources from being freely available. Rather it is a requirement to consider the direct costs and expertise of maintaining digital outputs for continued access. Some applicants might be able to demonstrate that there will be no significant sustainability problems with their digital output; in some cases the university’s computing services or library might provide a firm commitment to sustaining the resource for a specified period; others might see the benefit of Open Source community development models. You should provide reassurances of sustainability which are proportionate to the envisaged longer-term value of the digital outputs for the research community.

    When completing this section, you should consider the potential impact of the data on research in your field (if research in the discipline will be improved through the creation of the digital output, how will it be affected if the resource then disappears?), and make the necessary connections with your Impact Plan. You must factor in the effects of any IP, copyright and ethical issues during the period in which the digital output will be publicly accessible, connecting what you say with the relevant part of your Case for Support.

    You must identify whether or not you envisage the academic content (as distinct from the technology) of the digital output being extended or updated beyond the period of funding, addressing the following issues: how this will be done, by who and at what cost. You will need to show how the cost of this will be sustained after the period of funding ends.

    " - number: 2 - section: ahrc_4 - themes: resourcing_preservation_and_data_sharing, managed_access_procedures, data_repository, method_for_data_sharing, timeframe_for_data_sharing - -bbsrc_1_1: - text: "Data areas and data types - the volume, type and content of data that will be generated e.g. experimental measurements, models, records and images" - guidance: "

    BBSRC recognises that effective data sharing is already practiced in certain areas and expects this to continue. BBSRC supports, either directly or indirectly, a number of such resources. Data sharing in other areas is also expected where there is a strong scientific case and where it is cost effective.

    BBSRC has identified a number of areas where there is a particularly strong scientific case for data sharing. These are:

    • Data arising from high volume experimentation
    • Low throughput data arising from long time series or cumulative approaches
    • Models generated using systems approaches
    BBSRC expects data sharing to take place in these areas.

    " - number: 1 - section: bbsrc_1 - themes: description_of_data_content, data_type, data_volumes - -bbsrc_2_1: - text: "Standards and metadata - the standards and methodologies that will be adopted for data collection and management, and why these have been selected" - guidance: "

    Standards are fundamental to effective data sharing. These can include standards for administrative processes, as well as for methodologies relating to data management and data formats. Researchers are expected to make use of current guidance and information on best practice.

    It is expected that, in order to maximise the potential for re-use of data, BBSRC researchers should generate and manage data using existing widely accepted formats and methodologies where available. Data released for sharing should be validated and verified in line with accepted best practice and be of high quality. Data should be accompanied by the contextual information or documentation (metadata) needed to provide a secondary user with any necessary details on the origin or manipulation of the data in order to prevent any misuse, misinterpretation or confusion. Where standards for metadata exist, it is expected that these should be adhered to.

    BBSRC encourages community development of standards where these do not currently exist or are not widely accepted and provides funding mechanisms for support of this type of activity.

    " - number: 1 - section: bbsrc_2 - themes: data_format, metadata_standards, data_quality, documentation - -bbsrc_3_1: - text: "Relationship to other data available in public repositories" - guidance: "" - number: 1 - section: bbsrc_3 - themes: existing_data, relationship_to_existing data, licensing_of_existing data - -bbsrc_4_1: - text: "Secondary use - further intended and/or foreseeable research uses for the completed dataset(s)" - guidance: "

    BBSRC supports the view that those enabling sharing should receive full and appropriate recognition by funders, their academic institutions and new users for promoting secondary research.

    Where data are shared through a third party resource or databases, secondary users should acknowledge the source of data. Where data are shared directly from the originator, depending on the level of usage and collaboration either joint authorship or acknowledgement to the data originator may be appropriate. It is also important to ensure that researchers and their research institutions are protected against claims that application of their data led to wrong conclusions/decisions by others: any use made of any data generated by third parties would not come with a warranty of its quality.

    Furthermore, BBSRC expects that researchers accessing data have responsibilities to preserve data confidentiality and to observe the ethical and legal obligations pertaining to the data.

    " - number: 1 - section: bbsrc_4 - themes: expected_reuse, audience - -bbsrc_5_1: - text: "Methods for data sharing - planned mechanisms for making these data available, e.g. through deposition in existing public databases or on request, including access mechanisms where appropriate" - guidance: "

    BBSRC recognises that different approaches to data sharing will be required in different situations and considers that it is most appropriate for researchers to determine their own strategies for data sharing and outline these within their research grant proposal(s). Applicants should consider where, how, and to whom their data should be made available.

    In addition, data sharing practices will change as areas of research develop and become more mature. This can be observed by looking at the areas of sequencing (i.e. well established mechanisms in place), microarrays (i.e. standards developed and being implemented) and systems biology (i.e. databases currently not well developed). Consideration should be given to what constitutes good practice in emerging areas of research.

    It is expected that data sharing strategies will fall into the two broad categories below.

    Data Sharing via a 3rd Party

    Data sharing via deposition in an existing database, repository or other community resource is expected where possible and researchers are encouraged to share data through mechanisms affording the widest availability for generating added value and enabling re-use.

    Researchers are encouraged to use existing infrastructure to facilitate data sharing where possible. BBSRC funds or otherwise supports a number of such resources. Where no such resources exist, applicants may consider sharing data via other third party mechanisms such as journal websites and / or open access repositories, many of which are now able to capture and share data underpinning publications.

    Direct Data Sharing: from Originator to Others

    This method of data sharing may be appropriate for areas where suitable third party mechanisms are not available. Researchers are expected to ensure that data are maintained for a period of 10 years after the completion of the research project in suitable accessible formats using established standards where possible such that the data can be made available on request in line with BBSRC guidance on good scientific practice. This may lead to collaboration between the new user and the original data creators, with the responsibilities and rights of all parties agreed at the outset.

    Other mechanisms for data sharing may be used where appropriate. These could include sharing data within closed communities or a combination of methods for different datasets. Specific access mechanisms could be appropriate for example where there are ethical considerations, a need to protect confidential data, or other reasons for limiting access.

    " - number: 1 - section: bbsrc_5 - themes: discovery_by_users, method_for_data_sharing, managed_access_procedures, data_repository - -bbsrc_6_1: - text: "Proprietary data - any restrictions on data sharing due to the need to protect proprietary or patentable data" - guidance: "

    In instances where BBSRC and a commercial partner jointly fund academic research work (for example LINK projects) there may be some restrictions over releasing data. Any such restrictions on data sharing due to co-funding arrangements should be set out in the “statement on data sharing” section of an application and will be considered when a grant application is peer reviewed. Applicants should also ensure they have obtained necessary clearances from relevant collaborators with regards to the content of the proposal including the data sharing plan in line with the BBSRC Research Grants Guide.

    " - number: 1 - section: bbsrc_6 - themes: ipr_ownership_and_licencing, restrictions_on_sharing - -bbsrc_7_1: - text: "Timeframes - timescales for public release of data" - guidance: "

    The value of data often depends on timeliness. Researchers have a legitimate interest in benefiting from their own time and effort in producing data, but not in prolonged exclusive use of these data. BBSRC expects that all data (with accompanying metadata) should be shared in a timely fashion as soon as it is verified. It is expected that timely release would generally be no later than the release through publication of the main findings and should be in-line with established best practice in the field. Where best practices does not exist release within three years of generation of the dataset is suggested as a guide.

    The timescale for release for the data may differ for several reasons, depending on the nature of the data. These reasons may include:

    • Scientific Area: Researchers are expected to make data available in-line with established practices within the relevant research community. Examples include:
      • Crystallography (Protein Data Bank) - the community has agreed a maximum 12-month delay between publishing the first paper on a structure and making coordinates public for secondary use.
      • Sequencing (EMBL Nucleotide Sequence database) – submitted data can be withheld from public access until publication of results but no later.
      • Metabolomics (MeT-RO) – Up to a six-month delay in publication can be requested.
      • Arabidopsis microarray data (NASC Affymetrix service) – all data are made available after a maximum one-year confidential period.
    • Intellectual Property (IP) issues and potential for commercialisation of research outputs: New knowledge generates patentable ideas. BBSRC is also driving a policy of Knowledge Transfer and strongly encourages the commercialisation of IP through various initiatives. BBSRC recognises the need for periods of exclusive use of data but considers that commercialisation of research does not preclude data sharing and should not unduly delay or prevent data sharing. Any IP issues or plans for commercialisation should be highlighted in the case for support of the grant application.
    • Length or scope of research project: Data from large studies may be released in waves as they become available or as they are published.

    " - number: 1 - section: bbsrc_7 - themes: timeframe_for_data_sharing - -bbsrc_8_1: - text: "Format of the final dataset" - guidance: "" - number: 1 - section: bbsrc_8 - themes: data_format - -cruk_1_1: - text: "The volume, type, content and format of the final dataset" - guidance: "" - number: 1 - section: cruk_1 - themes: description_of_data_content, data_format, data_volumes, data_type - -cruk_2_1: - text: "The standards that will be utilised for data collection and management" - guidance: "" - number: 1 - section: cruk_2 - themes: data_capture_methods, metadata_standards - -cruk_3_1: - text: "The metadata, documentation or other supporting material that should accompany the data for it to be interpreted correctly" - guidance: "

    For data sharing to be a success it is important that data are prepared in such a way that those using the dataset have a clear understanding of what the data mean so that they can be used appropriately. To enable this, applicants are encouraged to include with the dataset all the necessary information (metadata) describing the data and their format. This information should include such information as the methodology used to collect data, definitions of variables, units of measurement, any assumptions made, the format of the data, file type of the data etc. To support this researchers are strongly encouraged to utilise community standards to describe and structure data, (e.g. common terminology, minimum information guidelines and standard data exchange formats).

    " - number: 1 - section: cruk_3 - themes: documentation, metadata_capture, data_quality - -cruk_4_1: - text: "The method used to share data" - guidance: "

    The methods used to share data will be dependent on a number of factors such as the type, size, complexity and sensitivity of data. Data can be shared by any of the following methods:

    Under the auspices of the Principal Investigator

    Investigators sharing under their own auspices may securely send data to a requestor, or upload the data to their institutional website. Investigators should consider using a data-sharing agreement (see below) to impose appropriate limitations on the secondary use of the data.

    Through a third party

    Investigators can share their data by transferring it to a data archive facility to distribute more widely to the scientific community, to maintain documentation and meet reporting requirements. Data archives are particularly attractive for investigators concerned about managing a large volume of requests for data, vetting frivolous or inappropriate requests, or providing technical assistance for users seeking to help with analyses.

    Using a data enclave

    Datasets that cannot be distributed to the general public due to confidentially concerns, or third-party licensing or use agreements that prohibit redistribution, can be accessed through a data enclave. A data enclave provides a controlled secure environments in which eligible researchers can perform analyses using restricted data resources.

    Through a combination of methods

    Investigators may wish to share their data by a combination of the above methods or in different versions, in order to control the level of access permitted.

    " - number: 1 - section: cruk_4 - themes: discovery_by_users, method_for_data_sharing, data_repository - -cruk_5_1: - text: "The timescale for public release of data" - guidance: "

    As the value of data is often dependent on its timeliness Cancer Research UK expects that data sharing should occur in a timely manner. Cancer Research UK acknowledges that the investigators who generated the data have a legitimate interest in benefiting from their investment of time and effort and we therefore support the initial investigator having a reasonable period of private use of the data but not prolonged exclusive use.

    Cancer Research UK expects data to be released no later than the acceptance for publication of the main findings from the final dataset (unless restrictions from third party agreements or IP protection still apply) or on a timescale in line with the procedures of the relevant research area. For example, for crystallography data there is an agreed 12-month delay between publishing the first paper on a structure and making the co-ordinates public.

    With experiments carried out over an extended period of time, (e.g. population based studies), it is reasonable to expect that subsets of data analysed by the investigator(s) be made available for sharing. The investigator(s) can then continue to benefit from further reasonable periods of exclusive analysis while the dataset as a whole matures.

    " - number: 1 - section: cruk_5 - themes: timeframe_for_data_sharing - -cruk_6_1: - text: "The long-term preservation plan for the dataset" - guidance: "

    Once the funding for a project has ceased researchers should preserve all data resulting from that grant to ensure that data can be used for follow-up or new studies. Cancer Research UK expects that data be preserved and available for sharing with the science community for a minimum period of five years following the end of a research grant.

    " - number: 1 - section: cruk_6 - themes: preservation_plan - -cruk_7_1: - text: "Whether a data sharing agreement will be required" - guidance: "

    Data Sharing Agreements

    To ensure that data are used appropriately investigators may consider implementing a data sharing agreement that indicates the criteria for data access and conditions for research use. This can ensure the responsibilities of both parties, along with intellectual property, citation and publication rights are agreed at the outset. It may incorporate privacy and confidentiality standards, as needed, to ensure data security at the recipient site and prohibit manipulation of data. For further guidance on managing data access and the development of data sharing agreements please refer to the 'Samples and Data for Cancer Research: Template for Access Policy Development' document available from the NCRI website.

    Data Acknowledgement

    As a minimum, researchers using shared data are expected to acknowledge the investigators who generated the data upon which any published findings are based. When both parties have collaborated using a shared dataset, co-authorship on publications may be more appropriate. Researchers using shared data are also expected to acknowledge Cancer Research UK for supporting the original study.

    " - number: 1 - section: cruk_7 - themes: managed_access_procedures - -cruk_8_1: - text: "Any reasons why there may be restrictions on data sharing?" - guidance: "

    Data which might have the potential to be exploited commercially or otherwise to deliver patient benefit should be discussed with your technology transfer office and Cancer Research Technology prior to data sharing. Cancer Research UK encourages the appropriate filing of patents and recognises that there may be a need to delay the release of data until patent applications have been filed. Whilst there may be a delay in the release of data due to the application process, appropriate intellectual property protection should not hinder data sharing and may be the best way of ensuring that patient (and public) benefit is delivered. Any intellectual property issues or plans for commercialisation that may affect data sharing should be addressed in the data sharing plan. Cancer Research UK understands that unexpected intellectual property may arise during the course of the study and investigators may need to depart from their data sharing plan to protect intellectual property and for any other necessary steps to be taken. Data sharing may also be affected when co-funding is provided by the private sector (e.g. by a pharmaceutical company) or host institution resulting in some restrictions on the disclosure of data. For example with clinical trials, the Trial Management Group and/or trial sponsor etc may impose restrictions on data access. Any restrictions should be outlined in the data sharing plan and applicants should explore ways data sharing requests can be considered by the body that owns the data.

    e.g. Development arrangements through Cancer Research Technology including intellectual property protection and commercialisation

    e.g. Proprietary Data - restrictions due to collaborations with for profit organisations International policies governing the sharing of data collected outside of the UK

    My research seeks supports from both the public and private sectors. How do I deal with the sharing of data? Where research is funded by a commercial sponsor, restrictions on data sharing may apply in arrangements agreed with the sponsor. Any such restriction(s) should be highlighted in the data management and sharing plan. In the event that researchers apply for or receive commercial funding for any part of their research that Cancer Research UK supports they should advise Cancer Research Technology of the situation without delay.

    e.g. Confidentiality, ethical or consent issues that may arise with the use of data involving human subjects.

    Investigators carrying out research involving human participants must ensure that consent is obtained to share information; furthermore the necessary legal, ethical and regulatory permissions regarding data sharing should be in place prior to disclosing any data. Every effort must be made to protect the identity of participants and, prior to sharing, data should be anonymised. In addition, any indirect identifiers that may lead to deductive disclosures should be removed to reduce the risk of identification. In most instances, sharing data should be possible without compromising the confidentiality of participants but if there are circumstances where data needs to be restricted due to the inability to protect confidentiality this should be fully addressed in the data management and sharing plan.

    " - number: 1 - section: cruk_8 - themes: restrictions_on_sharing, ipr_ownership_and_licencing, licensing_of_existing_data, ethical_issues - -esrc_1_1: - text: "An explanation of the existing data sources that will be used by the research project (with references)" - guidance: "

    When creating new data sources, explain why existing data sources can not be re-used. If purchasing or re-using existing data sources, explain whether issues such as copyright and IPR have been addressed to ensure that the data can be shared i.e. explain how you plan to deal with permissions to share data you have created which is derived from data which you do not own.

    The following sources can be reviewed for the availability of existing data that could be used:

    • Data Catalogue - an integrated catalogue containing over 5,000 datasets covering an extensive range of key economic, social and historical data - both quantitative and qualitative - spanning many disciplines and themes, and with links to census data
    • ESRC Research Catalogue - the ESRC's repository of past and present research awards and their outputs

    " - number: 1 - section: esrc_1 - themes: existing_data, licensing_of_existing_data - -esrc_1_2: - text: "An analysis of the gaps identified between the currently available and required data for the research" - guidance: "

    When creating new data sources, explain why existing data sources can not be re-used. If purchasing or re-using existing data sources, explain whether issues such as copyright and IPR have been addressed to ensure that the data can be shared i.e. explain how you plan to deal with permissions to share data you have created which is derived from data which you do not own.

    The following sources can be reviewed for the availability of existing data that could be used:

    • Data Catalogue - an integrated catalogue containing over 5,000 datasets covering an extensive range of key economic, social and historical data - both quantitative and qualitative - spanning many disciplines and themes, and with links to census data
    • ESRC Research Catalogue - the ESRC's repository of past and present research awards and their outputs

    " - number: 2 - section: esrc_1 - themes: relationship_to_existing_data - -esrc_2_1: - text: "Data volume and data type, e.g. qualitative or quantitative data" - guidance: "

    Give a brief description of new data which you envisage creating. This information should include how the data will be collected (in line with the proposed research methods), their format (e.g. SPSS, Open Document Format, tab-delimited format, MS Excel), and how they will be documented.

    Using standardised and interchangeable or open lossless data formats ensures the long-term usability of data. Clear and detailed data descriptions and annotation, together with user-friendly accompanying documentation on methods and contextual information, makes data easy to understand and interpret and therefore shareable and with long-lasting usability.

    " - number: 1 - section: esrc_2 - themes: data_volumes, data_type - -esrc_2_2: - text: "Data quality, formats, standards documentation and metadata" - guidance: "

    Give a brief description of new data which you envisage creating. This information should include how the data will be collected (in line with the proposed research methods), their format (e.g. SPSS, Open Document Format, tab-delimited format, MS Excel), and how they will be documented.

    Using standardised and interchangeable or open lossless data formats ensures the long-term usability of data. Clear and detailed data descriptions and annotation, together with user-friendly accompanying documentation on methods and contextual information, makes data easy to understand and interpret and therefore shareable and with long-lasting usability.

    " - number: 2 - section: esrc_2 - themes: data_format, metadata_standards, documentation - -esrc_2_3: - text: "Methodologies for data collection" - guidance: "

    Give a brief description of new data which you envisage creating. This information should include how the data will be collected (in line with the proposed research methods), their format (e.g. SPSS, Open Document Format, tab-delimited format, MS Excel), and how they will be documented.

    Using standardised and interchangeable or open lossless data formats ensures the long-term usability of data. Clear and detailed data descriptions and annotation, together with user-friendly accompanying documentation on methods and contextual information, makes data easy to understand and interpret and therefore shareable and with long-lasting usability.

    " - number: 3 - section: esrc_2 - themes: data_capture_methods - -esrc_3_1: - text: "Quality Assurance" - guidance: "

    Quality control of data is an integral part of a research process. Describe the procedures for quality assurance that will be carried out on the data collected at the time of data collection, data entry, digitisation and data checking.

    For example this might include:

    • Documenting the calibration of instruments
    • Taking duplicate samples or measurements
    • Standardised data capture, data entry or recording methods
    • Data entry validation techniques
    • Methods of transcription
    • Peer review of data

    " - number: 1 - section: esrc_3 - themes: data_quality - -esrc_3_2: - text: "Back-Up" - guidance: "

    Describe the data back-up procedures that you will adopt to ensure the data and metadata are securely stored during the lifetime of the project. You may need to discuss your institution's policy on back-ups. If your data is sensitive (e.g. detailed personal data) you should discuss appropriate security measures which you will be taking.

    The methods of version control of data files should also be stated. Version control includes making sure that if the information in one file is altered, the related information in other files is also adapted, as well as keeping track of versions of data files and their locations.

    " - number: 2 - section: esrc_3 - themes: backup_procedures, data_security, data_organisation - -esrc_4_1: - text: "Plans for management and archiving of collected data" - guidance: "

    Outline your plans for preparing and documenting data for sharing and archiving (unless otherwise agreed). Identify any additional plans for data sharing, if any. A crucial part of making data user-friendly, shareable and with long-lasting usability is to ensure they can be understood and interpreted by other users. This requires clear and detailed data description, annotation and contextual information.

    " - number: 1 - section: esrc_4 - themes: data_selection, preservation_plan, documentation - -esrc_5_1: - text: "Expected difficulties in data sharing, along with causes and possible measures to overcome these difficulties." - guidance: "

    We require that all applicants seeking ESRC funding include a statement on data sharing in the relevant section of the Je-S application form. If data sharing is not possible, the applicant must present a strong argument to justify their case. We reserve the right to decline the request or demand additional information from the applicant.

    Data Protection and Freedom of Information

    We expect grant holders to adhere to the Data Protection Act 1998, which contains eight (enforceable) principles of good practice, applying to anyone processing personal data, including the use of personal data in research. These include obtaining the data subject’s consent or meeting at least one of the ‘necessary’ conditions described in the Act.

    The ESRC complies with the requirements of the Freedom of Information Act 2000 that establishes a general right of access to all types of recorded information held by public authorities, including Government Departments and Non-Departmental Public Bodies.

    If the Principal Investigator does not state to the contrary in the Je-S application form, it will be assumed that they are willing for their contact details and other relevant information to be shared with the relevant data service provider working with the ESRC.

    " - number: 1 - section: esrc_5 - themes: restrictions_on_sharing, managed_access_procedures - -esrc_6_1: - text: "Explicit mention of consent, confidentiality, anonymisation and other ethical considerations" - guidance: "

    In facilitating innovative and high quality research, we require that the research we supports will be carried out to a high ethical standard. ESRC grant holders are, therefore, required to adhere to the key principles of ethical research addressed in the ESRC Framework for Research Ethics

    " - number: 1 - section: esrc_6 - themes: ethical_issues - -esrc_7_1: - text: "Copyright and intellectual property ownership of the data" - guidance: "

    Intellectual Property Rights

    In respect of research grant funding, unless stated otherwise, the ownership of intellectual property and responsibility for its exploitation, rests with the organisation carrying out the research. The ESRC may, in specific cases, reserve the right to retain ownership of the intellectual property and to arrange for it to be exploited for the national benefit in other ways. If exercised, this condition is included in the terms of the relevant award.

    In taking responsibility for exploiting intellectual property, we expect the research organisation to ensure that individuals associated with the research understand the arrangements for exploitation. Where research is funded by or undertaken in collaboration with others, the research organisation is responsible for putting appropriate formal agreements in place covering the contributions and rights of the various organisations and individuals involved. Such agreements must be in place before the research begins. Research organisations are required to ensure that the terms of collaboration agreements do not conflict with the Terms and Conditions for Research Council Grants.

    Copyright

    The ESRC expects grant holders to meet the copyright requirements set down in the Copyright, Designs and Patents Act 1988. Responsibility for ensuring compliance with all laws and other legal instruments rests with the grant holders and/or their institutions. We will not accept liability for any complaint or legal action taken against a researcher or the ESDS for infringements of copyrights, defamation or any other data protection requirements.

    " - number: 1 - section: esrc_7 - themes: ipr_ownership_and_licencing - -esrc_8_1: - text: "Responsibilities for data management and curation within research teams at all participating institutions" - guidance: "

    Indicate who within your research team will be responsible for data management, metadata production, dealing with quality issues and the final delivery of data for sharing or archiving. Provide this information within the Staff Duties section in the Je-S form and where appropriate in the Justification of Resources. If several people will be responsible state their roles and responsibilities in the relevant section of the Je-S form. For collaborative projects you should explain the co-ordination of data management responsibilities across partners in your Data Management Plan.

    " - number: 1 - section: esrc_8 - themes: project_data_contact, responsibilities - -nerc_1_1_1: - text: Data management procedures to be followed during the lifetime of the grant or fellowship - guidance: "

    Consider issues like:

    • metadata: will you document discovery (what, where, when, why, who) and descriptive (how collected, how processed, how stored, how linked) metadata and implement the NERC Discovery Metadata Standard (http://data-search.nerc.ac.uk/documents/metadatastandard_v1.0.pdf) early in the project?
    • data storage: have you access to enough storage and backup? Will you need specialist help with database design?
    • data quality: will there be an earmarked data manager within the team, what data quality checks will be used, will student data be integrated in the data plan?
    • ethical and access issues: are there special data security or licensing issues and how will you address these?

    " - number: 1 - section: nerc_1_1 - themes: metadata_capture, active_data_storage, data_quality, ethical_issues, managed_access_procedures - -nerc_1_2_1: - text: Existing datasets to be used by the grant or fellowship - guidance: "

    Comment on any restrictions on reuse.

    " - number: 1 - section: nerc_1_2 - themes: existing_data, licensing_of_existing_data - -nerc_1_3_1: - text: Data Centre - guidance: "

    The most appropriate NERC Data Centre – projects can contribute to more than one Data Centre.

    " - number: 1 - section: nerc_1_3 - themes: data_repository - -nerc_1_3_2: - text: Data Description - guidance: "

    1-2 sentences describing the data.

    " - number: 2 - section: nerc_1_3 - themes: description_of_data_content - -nerc_1_3_3: - text: Release Date to Data Centre - guidance: "

    Data should normally be delivered to a data centre within 2 years of collection.

    " - number: 3 - section: nerc_1_3 - themes: timeframe_for_data_sharing - -nerc_1_3_4: - text: Reuse Scenarios - guidance: "

    Possible user types and estimate of numbers if possible.

    " - number: 4 - section: nerc_1_3 - themes: expected_reuse - -nerc_2_1_1: - text: Nominated Data Centre - number: 1 - section: nerc_2_1 - themes: data_repository - -nerc_2_1_2: - text: Data Centre Contact - number: 2 - section: nerc_2_1 - -nerc_2_1_3: - text: Please specify any other team members with responsibility for data - number: 3 - section: nerc_2_1 - -nerc_2_2_1: - text: Roles and Responsibilities - guidance: "

    For example: who is responsible for obtaining 3rd party data, for capturing data in the field, producing metadata, transferring metadata and data to DDC.

    " - number: 1 - section: nerc_2_2 - themes: responsibilities - -nerc_2_3_1: - text: Data Generation Activities - guidance: "

    Short description of the what, how much, when and how etc.

    " - number: 1 - section: nerc_2_3 - themes: data_capture_methods - -nerc_2_4_1: - text: In-Project Data Management Approach - guidance: "

    Statement about how the data will be managed within the project, including backup & security.

    " - number: 1 - section: nerc_2_4 - themes: active_data_storage, backup_procedures, data_security - -nerc_2_5_1: - text: Metadata and Documentation - guidance: "

    Insert statement about how metadata will be supplied and standards to which it will adhere.

    " - number: 1 - section: nerc_2_5 - themes: metadata_capture, metadata_standards - -nerc_2_6_1: - text: Data Quality - guidance: "

    List procedures for quality control of data.

    " - number: 1 - section: nerc_2_6 - themes: data_quality - -nerc_2_7_1: - text: Exceptions or Additional Services - guidance: "

    Any exceptional expectations of Data Centres (for example exceptional size or complexity) - funding for which should be included within the project's Directly Incurred costs and explained within the Justification of Resources attachment.

    " - number: 1 - section: nerc_2_7 - themes: resourcing_preservation_and_data_sharing - -nerc_2_8_1: - text: Digital Information - guidance: "

    Enter a brief description of the activities that will produce the data.

    " - number: 1 - section: nerc_2_8 - themes: data_capture_methods, description_of_data_content, project_data_contact, data_volumes, data_format, ipr_ownership_and_licencing, timeframe_for_data_sharing, timeframe_for_data_sharing, expected_reuse, preservation_plan - -nerc_2_8_2: - text: Hardcopy Records - guidance: "

    Enter a brief description of the activities that will produce the data.

    " - number: 2 - section: nerc_2_8 - themes: data_capture_methods, project_data_contact, data_volumes, data_format, ipr_ownership_and_licencing, timeframe_for_data_sharing, preservation_plan - -nerc_2_8_3: - text: Physical Collections & Samples - guidance: "

    Enter a brief description of the activities that will produce the data

    " - number: 3 - section: nerc_2_8 - themes: data_capture_methods,project_data_contact,data_volumes,data_format,ipr_ownership_and_licencing,timeframe_for_data_sharing,preservation_plan - -nerc_2_9_1: - text: Third Party/Existing Datasets - number: 1 - section: nerc_2_9 - themes: existing_data, data_volumes, responsibilities, licensing_of_existing_data, restrictions_on_sharing - -mrc_1_1: - text: Type of Study - guidance: "

    Up to three lines of text that summarise the type of study (or studies) for which the data are being collected.

    " - number: 1 - section: mrc_1 - themes: project_description - -mrc_1_2: - text: Types of Data - guidance: "

    Types of research data to be managed in the following terms: quantitative, qualitative; generated from surveys, clinical measurements, interviews, medical records, electronic health records, administrative records, genotypic data, images, tissue samples,...

    " - number: 2 - section: mrc_1 - themes: data_type - -mrc_1_3: - text: Format and scale of the data - guidance: "

    File formats, software used, number of records, databases, sweeps, repetitions,… (in terms that are meaningful in your field of research). Do formats and software enable sharing and long-term validity of data?

    " - number: 1 - section: mrc_1 - themes: data_format, data_volumes - -mrc_2_1: - text: Methodologies for data collection / generation - guidance: "

    How the data will be collected/generated and which community data standards (if any) will be used at this stage.

    " - number: 1 - section: mrc_2 - themes: data_capture_methods - -mrc_2_2: - text: Data quality and standards - guidance: "

    How consistency and quality of data collection / generation will be controlled and documented, through processes of calibration, repeat samples or measurements, standardised data capture or recording, data entry validation, peer review of data or representation with controlled vocabularies.

    " - number: 2 - section: mrc_2 - themes: data_quality, documentation - -mrc_3_1: - text: Managing, storing and curating data - guidance: "

    Briefly, how data will be stored, backed-up, managed and curated in the short to medium term. Specify any community agreed or other formal data standards used (with URL references). [Enter data security standards in Section 4].

    " - number: 1 - section: mrc_3 - themes: active_data_storage, backup_procedures - -mrc_3_2: - text: Metadata standards and data documentation - guidance: "

    Plans for documenting, annotating and describing data so that research data are usable by others than your own team. This may include documenting the methods used to generate the data, analytical and procedural information, capturing instrument metadata alongside data, documenting provenance of data and their coding, detailed descriptions for variables, records, etc.

    " - number: 2 - section: mrc_3 - themes: metadata_standards, documentation - -mrc_3_3: - text: Data preservation strategy and standards - guidance: "

    Plans and place for long-term storage, preservation and planned retention period for the research data. Formal preservation standards, if any. Indicate which data may not be retained (if any).

    " - number: 3 - section: mrc_3 - themes: preservation_plan, data_repository, period_of_preservation - -mrc_4_1: - text: Formal information/data security standards - guidance: "

    Identify formal information standards with which your study is or will be compliant. An example is ISO 27001.

    " - number: 1 - section: mrc_4 - themes: data_security - -mrc_4_2: - text: Main risks to data security - guidance: "

    If not using formal standards, summarise the main risks to the confidentiality and security of information related to human participants, and how these risks will be managed. Cover the main processes or facilities for storage and processing of personal data, data access, with controls put in place and any auditing of user compliance with consent and security conditions.

    MRC guidance on the categories of data availability is provided.

    " - number: 2 - section: mrc_4 - themes: data_security - -mrc_5_1: - text: Data sharing and access - guidance: "

    Identify any data repository (-ies) that are, or will be, entrusted with storing, curating and/or sharing data from your study, where they exist for particular disciplinary domains or data types. Information on repositories is available here.

    " - number: 1 - section: mrc_5 - themes: data_repository - -mrc_5_2: - text: Suitability for sharing - guidance: "

    Indicate whether the data you propose to collect (or existing data you propose to use) in the study will be suitable for sharing. (“Yes” or “No”)

    If “No,” indicate why they will not be suitable for sharing and then go to Section 6.

    " - number: 2 - section: mrc_5 - -mrc_5_3: - text: Discovery by potential users of the research data - guidance: "

    Indicate how potential new users can find out about your data and identify whether they could be suitable for their research purposes, e.g. through summary information (metadata) being readily available on the study website, in the MRC gateway for population and patient research data, or in other databases or catalogues. Indicate whether your policy or approach to data sharing is (or will be) published on your study website (or by other means).

    " - number: 3 - section: mrc_5 - themes: discovery_by_users - -mrc_5_4: - text: Governance of access - guidance: "

    Identify who makes or will make the decision on whether to supply research data to a potential new user.

    For population health and patient-based research, indicate how independent oversight of data access and sharing works (or will work) in compliance with MRC policy.

    Indicate whether the research data will be deposited in and available from an identified community database, repository, archive or other infrastructure established to curate and share data.

    " - number: 4 - section: mrc_5 - themes: managed_access_procedures, method_for_data_sharing - -mrc_5_5: - text: The study team’s exclusive use of the data - guidance: "

    MRC’s requirement is for timely data sharing, with the understanding that a limited, defined period of exclusive use of data for primary research is reasonable according to the nature and value of the data, and that this restriction on sharing should be based on simple, clear principles.

    Summarise the principles of your current/intended policy.

    " - number: 5 - section: mrc_5 - themes: timeframe_for_data_sharing - -mrc_5_6: - text: Restrictions or delays to sharing, with planned actions to limit such restrictions - guidance: "

    Restriction to data sharing may be due to participant confidentiality, consent agreements or IPR. Strategies to limit restrictions may include data being anonymised or aggregated; gaining participant consent for data sharing; gaining copyright permissions. For prospective studies, consent procedures should include provision for data sharing to maximise the value of the data for wider research use, while providing adequate safeguards for participants. As part of the consent process, proposed procedures for data sharing should be set out clearly and current and potential future risks associated with this explained to research participants.

    " - number: 6 - section: mrc_5 - themes: restrictions_on_sharing - -mrc_5_7: - text: Regulation of responsibilities of users - guidance: "

    Indicate whether external users are (will be) bound by data sharing agreements, setting out their main responsibilities.

    " - number: 7 - section: mrc_5 - themes: managed_access_procedures - -mrc_6_1: - text: Responsibilities - guidance: "

    Specify who, alongside the PI, is responsible for ensuring the study-wide data management, as well as for specific roles such as metadata creation, data security and quality assurance of data.

    " - number: 1 - section: mrc_6 - themes: responsibilities - -mrc_6_2: - text: Relevant institutional, departmental or study policies on data sharing and data security - guidance: "

    List policy, URL & reference

    Please complete, where such policies are (i) relevant to your study, and (ii) are in the public domain, e.g. accessibly through the internet. Add any others that are relevant

    " - number: 2 - section: mrc_6 - themes: related_policies - -stfc_1_1: - text: Specify the types of data the research will generate. - guidance: "

    Data management plans should describe the types of data that are expected to be produced from the project, including the raw data arising directly from the research, the reduced data derived from it, and published data.

    " - number: 1 - section: stfc_1 - themes: data_type - -stfc_2_1: - text: Specify which data will be preserved and how. - guidance: "

    Unless there are compelling reasons not to do so, STFC expects data to be managed through an established repository, chosen to maximise the scientific value from aggregation of related data. This may be at the grant holder's institution or elsewhere. Data management plans may refer to the general policies of the chosen repository and only include further details if necessary to the specific project. (If it is proposed not to use an established repository, the data management plan will need to demonstrate that resources and systems will be in place to enable the data to be curated effectively beyond the lifetime of the grant, although STFC recognises that applicants may not have the expertise to describe in detail how data will be curated).

    " - number: 1 - section: stfc_2 - themes: data_selection, preservation_plan, data_repository - -stfc_3_1: - text: Specify the software and metadata implications. - guidance: "

    The data management plan should specify the software and metadata that will be retained to enable the data to be read and interpreted.

    " - number: 1 - section: stfc_3 - themes: documentation, metadata_standards - -stfc_4_1: - text: Specify for how long the data will be preserved. - guidance: "

    This may depend on the type of data. Where possible, STFC expects the original data, from which other related data can in principle be derived, to be retained for a minimum of 10 years from the end of the project. For data that by their nature cannot be re-measured, efforts should be made to retain them indefinitely.

    " - number: 1 - section: stfc_4 - themes: period_of_preservation - -stfc_5_1: - text: Specify and justify which data will have value to others and should be shared. - guidance: "

    Any data that are shared should be of a sufficiently high quality to be of value to other researchers. In general, published data – data that are displayed or otherwise referred to in a publication – should be made publicly available, but it is for applicants to consider and justify which types of data will, in the context of their project, meaningfully and practically constitute published data. Publicly available means available to anyone, but there may be a requirement for registration to enable tracking of data use and to provide notification of terms and conditions of use where they apply. Other data should be made available wherever it is appropriate and cost-effective to do so, taking into account the cost of curation compared with the cost or feasibility of re-creation, the potential long-term demand for the data and the feasibility of their reuse by others.

    " - number: 1 - section: stfc_5 - themes: audience, expected_reuse, data_selection - -stfc_6_1: - text: Specify and justify the length of any proprietary period. - guidance: "

    This might for example refer to the reasonable needs of the research team to have a first opportunity to exploit the results of their research, including any intellectual property arising. Where there are accepted norms within a scientific field or specific archive they should normally be followed. In general, STFC expects that published data should be made publicly available within six months of publication unless justified otherwise.

    " - number: 1 - section: stfc_6 - themes: timeframe_for_data_sharing - -stfc_7_1: - text: Specify how data will be shared - guidance: "

    The minimum level of data sharing expected would be that of making the data available in the natural format in which they were created, along with documentation and metadata, according to the standard accepted procedures within the scientific field. Where the data are likely to be in great demand by others it may be appropriate to request resources for a more proactive approach to data sharing, which maximises opportunities for cross linkage with other sectors.

    " - number: 1 - section: stfc_7 - themes: method_for_data_sharing - -stfc_8_1: - text: Specify and justify any resources required to preserve and share the data. - guidance: "

    Wherever possible, data management should make use of existing skills and capabilities. However, justification should be made for any additional specialist staff (or training for existing staff) needed within the grant to enable the research team to manage, preserve and share data effectively; and for any computational facilities needed to manage, store and share the data generated by the research.

    " - number: 1 - section: stfc_8 - themes: resourcing_preservation_and_data_sharing, resourcing_skills_and_training - -wellcome_1_1: - text: What data outputs will your research generate and what data will have value to other researchers? - guidance: "

    Researchers should maximise access to research datasets of value to the wider research community in a timely and responsible manner. Any data that is shared should be of a sufficiently high quality that it will have value to other researchers and should be provided in a format that enables it to be used effectively.

    We recognise that in some cases it may not be appropriate for researchers to share their data. However, if your research meets the criteria for requiring a data management and sharing plan but you are intending not to share your data, the reasons for this must be clearly justified.

    Data should be shared in accordance with recognised data standards where these exist, and in a way that maximises opportunities for data linkage and interoperability. Sufficient metadata must be provided to enable the dataset to be used by others. Agreed best practice standards for metadata provision should be adopted where these are in place.

    When developing data management and sharing plans, researchers should therefore consider and briefly describe:

    • what types of data the proposed research will generate?
    • which data will have value to other research users and could be shared?
    • what data formats and quality standards will be applied to enable the data to be shared effectively?

    " - number: 1 - section: wellcome_1 - themes: description_of_data_content, data_selection, audience, data_format, data_quality, data_type - -wellcome_2_1: - text: When will you share the data? - guidance: "

    All data management and sharing plans must state clearly the timescales over which datasets of value will be shared. Such timescales should take account of any recognised standards of good practice in the applicant's research field.

    In considering the timescales that are appropriate, the Trust recognises fully that data generators have the right to a reasonable (but not unlimited) period of exclusive use for the research data that they produce.

    As set out in our guidelines on good research practice, all grant holders must ensure as an absolute minimum that the data underpinning research papers are made available to other researchers on publication, providing this is consistent with any ethics approvals and consents which cover the data and any intellectual property rights in them.

    In cases where the creation of a database resource is the primary goal of a Trust-funded activity, we would normally expect the data to be made widely available to user communities at the earliest feasible opportunity.

    In line with the Fort Lauderdale Principles and subsequent Toronto statement on pre-publication data sharing, the Trust also encourages timely and responsible pre-publication data sharing for research that might constitute a \"community resource\" (i.e. those that have the characteristics set out in point 7 above).

    Where appropriate, researchers may use publication moratoria to facilitate pre-publication sharing of data with other researchers, while protecting their right to first publication. Any such restrictions on data use should be reasonable, transparent and in line with established best practice.

    Illustrative examples of timescales for data sharing are provided to help demonstrate different models that have been adopted and may be considered as examples of good practice in the field of large-scale genetics and genomics studies.

    " - number: 1 - section: wellcome_2 - themes: timeframe_for_data_sharing - -wellcome_3_1: - text: Where will you make the data available? - guidance: "

    Researchers should deposit data in recognised data repositories where these exist for particular data types, unless there is a compelling reason not to do so. Further information on repositories that may be appropriate

    If the intention is to create a tailored database resource or to store data locally, researchers should ensure that they have the resources and systems in place so that the data are curated, secured and shared in an way that maximises its value and safeguards any associated risks.This includes consideration of how data held in this way can be effectively linked and integrated with other datasets to enhance its value to users.

    " - number: 1 - section: wellcome_3 - themes: method_for_data_sharing, data_repository - -wellcome_4_1: - text: How will other researchers be able to access the data? - guidance: "

    Data should be made available to other researchers with as few restrictions as possible. Where a managed access process is required - for example, where a study involves potentially identifiable data about research participants - the access mechanisms established should be proportionate to the risks associated with the data, and must not unduly restrict or delay access. Any managed access procedures that are proposed must be described clearly as part of your data management and sharing plan.

    Depending on the study, it may be appropriate to establish a graded access procedure in which less sensitive data (e.g. anonymised and aggregate data) are made readily available, whereas applications to access to more sensitive datasets are subject to a more stringent assessment process.

    Any managed access procedures should be consistent and transparent. In cases where a Data Access Committee is required to assess applications to access data, the composition of such Committees should include individuals with appropriate expertise who are independent of the project.

    Where appropriate, the Trust would encourage those generating datasets that are likely to be of significant value to other researchers to publish a 'marker paper' or other form of publication, which enables data users to formally cite their usage of the resource.

    Where a database resource is being developed as part of a funded activity, researchers should take reasonable steps to ensure that potential users are made aware of its availability. These should be outlined briefly in your plan.

    " - number: 1 - section: wellcome_4 - themes: managed_access_procedures, method_for_data_sharing - -wellcome_5_1: - text: Are any limits to data sharing required - for example, to either safeguard research participants or to gain appropriate intellectual property protection? - guidance: "

    For some research, delays or limits on data sharing may be necessary and appropriate to safeguard research participants or to ensure intellectual property protection is gained. Any such restrictions should, however, be minimised as far as feasible and set out clearly in data management and sharing plans where these are required.

    Safeguarding Research Participants

    For research involving samples or information pertaining to human subjects, data must be managed and shared in a way which is fully consistent with the terms of the consent under which samples and data were provided by the research participants.

    For prospective studies, consent procedures should include provision for data sharing in a way that maximises the value of the data for wider research use, while providing adequate safeguards for participants. As part of the consent process, proposed procedures for data sharing should be set out clearly and current and potential future risks associated with this explained to research participants.

    In designing studies, researchers must ensure that they have appropriate systems to protect the confidentiality and security of data pertaining to human subjects, and minimise any risks of identification by data users. This can be achieved through the use of appropriate anonymisation procedures and managed access processes. Such systems should be sufficient to safeguard participants, but proportionate to the level of sensitivity of the data and associated risk. They should not unduly inhibit responsible data sharing for legitimate research uses.

    Intellectual Property

    In line with our policy on intellectual property and patenting, we expect our funded researchers to ensure that any intellectual property in the outputs of their research is suitably protected and managed in a way that best enables the use of that knowledge for ultimate health benefit.

    Delays or restrictions on data sharing may be appropriate to gain intellectual property protection or to further development of a technology for public benefit. As noted above, any such limits should be minimised as far as is feasible.

    " - number: 1 - section: wellcome_5 - themes: restrictions_on_sharing, data_security, ethical_issues, ipr_ownership_and_licencing - -wellcome_6_1: - text: How will you ensure that key datasets are preserved to ensure their long-term value? - guidance: "

    Researchers must consider how datasets that have long-term value will be preserved and curated beyond the lifetime of the grant. If the proposal is to create a bespoke data resource or to store data locally rather than to use a recognised data repository, data management plans should state clearly how the applicant expects that the dataset will be preserved and shared when the period of grant funding comes to an end.

    The Trust is happy to discuss issues relating to longer-term preservation and sustainability with researchers so as to help provide the support required to maximise the long-term value of key research datasets.

    " - number: 1 - section: wellcome_6 - themes: preservation_plan, data_repository - -wellcome_7_1: - text: What resources will you require to deliver your plan? - guidance: "

    In preparing data management and sharing plans, researchers should consider carefully any resources they may need to deliver their plan.Where dedicated resources are required, these should be outlined and justified as part of the plan.

    Issues to consider include:

    • People and skills - is there sufficient expertise and resource in the research team to manage, preserve and share the data effectively?Is additional specialist expertise (or training for existing staff) required? If so, how will this be sourced?
    • Infrastructure - are there appropriate computational facilities to manage, store and analyse the data generated by the research?
    • Tools - will additional computational facilities and resources need to be accessed, and what will be the costs associated with this?

    " - number: 1 - section: wellcome_7 - themes: resourcing_skills_and_training, resourcing_hardware_and_software, resourcing_preservation_and_data_sharing diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml deleted file mode 100644 index 5da7d93..0000000 --- a/test/fixtures/roles.yml +++ /dev/null @@ -1,5 +0,0 @@ -<% # Load the roles from those defined within the MagicStrings section of the locale %> -<% I18n.t("magic_strings.user_role_types").each do |k,v| %> -<%= v %>: - name: <%= "#{v}" %> -<% end %> diff --git a/test/fixtures/sections.yml b/test/fixtures/sections.yml deleted file mode 100644 index ae406fd..0000000 --- a/test/fixtures/sections.yml +++ /dev/null @@ -1,48 +0,0 @@ -# Produces: -# ----------------------------- -# Generates 2 Sections for each Version of a published template and 4 Sections for -# each Version of an unpublished template -# (see dmptemplates.yml, phases.yml and versions.yml) -# -# [template]_phase_1_version_1_section_[1..2] -# [template]_unpublished_phase_[1..2]_version_[1..2]_section_[1..4] -# -# The complete organisation has 2 sections attached to its template and 2 -# customisations -# -# complete_customised_template_phase_1_version_1_section_[1..2] -# - -# Import versions.yml so that we can dynamically generate sections -<% versions = YAML::load(ERB.new(File.read('./test/fixtures/versions.yml')).result) %> - -<% versions.each do |lbl, hash| %> - <% if lbl.include?('customised_') %> - - <% 2.times do |n| %> -<%= lbl %>_customisation_<%= n + 1 %>: - title: <%= "#{(n == 0) ? 'Licensing (Customisation)' : 'Access (Customisation)'}" %> - number: <%= 3 + n %> - version: <%= lbl %> - organisation: complete - <% end %> - - <% else %> - - <% 2.times do |x| %> -<%= lbl %>_section_<%= x + 1 %>: - title: <%= "#{(x == 0) ? 'Data Collection' : 'Storage and Backup'}" %> - number: <%= x + 1 %> - version: <%= lbl %> - <% end %> - - <% if lbl.include?('_unpublished') %> - <% 2.times do |y| %> -<%= lbl %>_section_<%= y + 3 %>: - title: <%= "#{(y == 0) ? 'Documentation' : 'Compliance'}" %> - number: <%= 3 + y %> - version: <%= lbl %> - <% end %> - <% end %> - <% end %> -<% end %> diff --git a/test/fixtures/themes.yml b/test/fixtures/themes.yml deleted file mode 100644 index d02ca85..0000000 --- a/test/fixtures/themes.yml +++ /dev/null @@ -1,176 +0,0 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - -related_policies: - title: Related Policies - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -existing_data: - title: Existing Data - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -licensing_of_existing_data: - title: Licensing of Existing Data - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -relationship_to_existing_data: - title: Relationship to Existing Data - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -description_of_data_content: - title: Description of Data Content - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_format: - title: Data Format - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_volumes: - title: Data Volumes - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_type: - title: Data Type - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_capture_methods: - title: Data Capture Methods - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_organisation: - title: Data Organisation - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_quality: - title: Data Quality - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -documentation: - title: Documentation - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -metadata_capture: - title: Metadata Capture - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -metadata_standards: - title: Metadata Standards - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -discovery_by_users: - title: Discovery by Users - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -ethical_issues: - title: Ethical Issues - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -ipr_ownership_and_licencing: - title: IPR Ownership and Licencing - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -active_data_storage: - title: Active Data Storage - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -backup_procedures: - title: Backup Procedures - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_security: - title: Data Security - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_selection: - title: Data Selection - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -preservation_plan: - title: Preservation Plan - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -period_of_preservation: - title: Period of Preservation - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -data_repository: - title: Data Repository - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -audience: - title: Audience - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -expected_reuse: - title: Expected Reuse - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -method_for_data_sharing: - title: Method For Data Sharing - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -timeframe_for_data_sharing: - title: Timeframe For Data Sharing - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -embargo_period: - title: Embargo Period - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -restrictions_on_sharing: - title: Restrictions on Sharing - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -managed_access_procedures: - title: Managed Access Procedures - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -responsibilities: - title: Responsibilities - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -resourcing_skills_and_training: - title: "Resourcing: Skills and Training" - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -resourcing_hardware_and_software: - title: "Resourcing: Hardware and Software" - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en - -resourcing_preservation_and_data_sharing: - title: "Resourcing: Preservation and Data Sharing" - description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - locale: en diff --git a/test/fixtures/token_permission_types.yml b/test/fixtures/token_permission_types.yml deleted file mode 100644 index 3c39e5b..0000000 --- a/test/fixtures/token_permission_types.yml +++ /dev/null @@ -1,7 +0,0 @@ -plans_token_type: - token_type: 'plans' - text_description: 'allows a user access to the plans api endpoint' - -guidances_token_type: - token_type: 'guidances' - text_description: 'allows a user access to the guidances api endpoint' \ No newline at end of file diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml deleted file mode 100644 index 250a3fc..0000000 --- a/test/fixtures/users.yml +++ /dev/null @@ -1,115 +0,0 @@ -# Produces: -# ----------------------------- -# cc_super -# cc_admin -# -# funder_admin -# -# complete_admin -# complete_user -# -# institution_[1..2]_admin -# institution_[1..2]_user -# -# school_[1..2]_admin -# school_[1..2]_user -# -# project_[1..2]_admin -# project_[1..2]_user -# - -# Import organisation_types.yml and roles.yml -<% organisation_types = YAML::load(ERB.new(File.read('./test/fixtures/organisation_types.yml')).result) %> - -cc_super: - firstname: 'Curation Centre' - surname: 'Super Admin' - email: 'super-admin@example-cc.org' - accept_terms: true - organisation: curation_center - roles: [add_organisations, change_org_affiliation, grant_api_to_orgs, grant_permissions, modify_templates, modify_guidance, change_org_details, use_api] - api_token: "ABCD1234ZYX987supercc" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - -cc_admin: - firstname: 'Curation Centre' - surname: 'Administrator' - email: 'admin@example-cc.org' - accept_terms: true - organisation: curation_center - roles: [grant_permissions, modify_templates, modify_guidance, change_org_details, use_api] - api_token: "ABCD1234ZYX987admincc" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - -funder_admin: - firstname: 'Funder' - surname: 'Administrator' - email: 'admin@example-funder.org' - accept_terms: true - organisation: funder - roles: [grant_permissions, modify_templates, modify_guidance, change_org_details, use_api] - api_token: "ABCD1234ZYX987adminfunder" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - -# We unfortunatley cannot tab this out nicely because YAML is expecting the values in -# the first column -<% organisation_types.each do |lbl, obj| %> - <% unless ['funder', 'organisation'].include?(lbl) %> - <% 2.times do |x| %> - -<%= lbl %>_<%= x + 1 %>_admin: - firstname: <%= "#{obj['name']} #{x + 1}" %> - surname: "Admin" - email: <%= "admin@example-#{lbl}-#{x + 1}.org" %> - orcid_id: <%= "orcid-#{lbl}-#{x + 1}-admin12345" %> - shibboleth_id: <%= "shib-#{lbl}-#{x + 1}-admin12345" %> - accept_terms: true - organisation: <%= lbl %>_<%= x + 1 %> - roles: [grant_permissions, modify_templates, modify_guidance, change_org_details, use_api] - api_token: "ABCD1234ZYX987admin#{lbl}#{x + 1}" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - -<%= lbl %>_<%= x + 1 %>_user: - firstname: <%= "#{obj['name']} #{x + 1}" %> - surname: "User" - email: <%= "user@example-#{lbl}-#{x + 1}.org" %> - orcid_id: <%= "orcid-#{lbl}-#{x + 1}-user12345" %> - shibboleth_id: <%= "shib-#{lbl}-#{x + 1}-user12345" %> - accept_terms: true - organisation: <%= lbl %>_<%= x + 1 %> - api_token: "ABCD1234ZYX987user#{lbl}#{x + 1}" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - - <% end %> - <% end %> -<% end %> - -complete_admin: - firstname: "Complete" - surname: "Admin" - email: <%= "admin@example-complete.org" %> - orcid_id: <%= "orcid-complete-admin12345" %> - shibboleth_id: <%= "shib-complete-admin12345" %> - accept_terms: true - organisation: complete - roles: [grant_permissions, modify_templates, modify_guidance, change_org_details, use_api] - api_token: "ABCD1234ZYX987admincomplete" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' - -complete_user: - firstname: "Complete" - surname: "User" - email: <%= "user@example-complete.org" %> - orcid_id: <%= "orcid-complete-user12345" %> - shibboleth_id: <%= "shib-complete-user12345" %> - accept_terms: true - organisation: complete - api_token: "ABCD1234ZYX987usercomplete" - language: en-UK - confirmed_at: '2016-09-09 10:10:10' \ No newline at end of file diff --git a/test/fixtures/versions.yml b/test/fixtures/versions.yml deleted file mode 100644 index d4e9758..0000000 --- a/test/fixtures/versions.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Produces: -# ----------------------------- -# Generates 1 Version for each Phase of a published template and 2 Versions for -# each Phase of an unpublished template -# (see dmptemplates.yml for template list and phases.yml for phase list) -# -# [template]_phase_1_version_1 -# [template]_unpublished_phase_[1..2]_version_[1..2] -# -# A copy of Funder Template 1 Phase 1 that contains customisations -# -# complete_template_customised_phase -# - -# Import phases.yml so that we can dynamically generate versions -<% phases = YAML::load(ERB.new(File.read('./test/fixtures/phases.yml')).result) %> - -<% phases.each do |lbl, hash| %> - -<%= lbl %>_version_1: - title: <%= "hash['title'] - Version 1" %> - number: 1 - published: true - phase: <%= lbl %> - - <% if lbl.include?('_unpublished') %> -<%= lbl %>_version_2: - title: <%= "hash['title'] - Version 2" %> - number: 2 - published: false - phase: <%= lbl %> - <% end %> - -<% end %> - -complete_customised_template_phase_1_version_1: - title: "Customisation of Funder Template 1, Phase 1, Version 1" - number: 1 - published: false - phase: funder_template_1_phase_1 \ No newline at end of file diff --git a/test/functional/annotations_controller_test.rb b/test/functional/annotations_controller_test.rb new file mode 100644 index 0000000..67c7756 --- /dev/null +++ b/test/functional/annotations_controller_test.rb @@ -0,0 +1,129 @@ +require 'test_helper' + +class AnnotationsControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @question = Annotation.first.question + + # Get the first Org Admin + scaffold_org_admin(@question.section.phase.template.org) + end + +# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has +# these defined. They are defined multiple times though and we need to clean this up! In particular +# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates. +# We should just have: +# +# SHOULD BE: +# -------------------------------------------------- +# suggested_answers GET /templates/:template_id/phases/:phase_id/sections/:section_id/questions/:id sections#index +# POST /templates/:template_id/phases/:phase_id/sections/:section_id/questions/:id sections#create +# suggested_answer GET /templates/:template_id/phases/:phase_id/sections/:section_id/questions/:question_id/suggested_answer/:id sections#show +# PATCH /templates/:template_id/phases/:phase_id/section/:section_id/questions/:question_id/suggested_answer/:id sections#update +# PUT /templates/:template_id/phases/:phase_id/section/:section_id/questions/:question_id/suggested_answer/:id sections#update +# DELETE /templates/:template_id/phases/:phase_id/section/:section_id/questions/:question_id/suggested_answer/:id sections#destroy +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# admin_create_suggested_answer POST /org/admin/templates/suggested_answers/:id/admin_create suggested_answers#admin_create +# admin_update_suggested_answer PUT /org/admin/templates/suggested_answers/:id/admin_update suggested_answers#admin_update +# admin_destroy_suggested_answer DELETE /org/admin/templates/suggested_answers/:id/admin_destroy suggested_answers#admin_destroy + + + + # POST /org/admin/templates/suggested_answers/:id/admin_create (admin_create_annotation_path) + # ---------------------------------------------------------- + test "create a new annotation" do + params_guid = {question_id: @question.id, guidance_text: "some guidance text"} + params_example = {question_id: @question.id, example_answer_text: "example answer text"} + params_both = {question_id: @question.id, example_answer_text: "example answer text", guidance_text: "some guidance text"} + + # Should redirect user to the root path if they are not logged in! + post admin_create_annotation_path(id: Annotation.first.id), params_both + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # both + post admin_create_annotation_path(id: Annotation.first.id), params_both + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal _('Information was successfully created.'), flash[:notice] + assert_equal "some guidance text", Annotation.last.text, "expected the guidance to have been created!" + assert_equal "example answer text", Annotation.all[-2].text, "expected the example answer to have been created" + # just an example answer + post admin_create_annotation_path(id: Annotation.first.id), params_example + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal _('Information was successfully created.'), flash[:notice] + assert_equal "example answer text", Annotation.last.text, "expected the record to have been created!" + # just some guidance + post admin_create_annotation_path(id: Annotation.first.id), params_guid + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal _('Information was successfully created.'), flash[:notice] + assert_equal "some guidance text", Annotation.last.text, "expected the record to have been created!" + + end + + # PUT /org/admin/templates/suggested_answers/:id/admin_update (admin_update_suggested_answer_path) + # ---------------------------------------------------------- + test "update the annotation" do + q = Annotation.first.question + params_guid = {question_id: q.id, guidance_id: Annotation.first.id ,guidance_text: 'UPDATE'} + params_example = {question_id: q.id, example_answer_id: Annotation.first.id, example_answer_text: 'UPDATE'} + params_both = {question_id: q.id, guidance_id: Annotation.first.id ,guidance_text: 'gUPDATE',example_answer_id: Annotation.last.id, example_answer_text: 'eUPDATE'} + + # Should redirect user to the root path if they are not logged in! + put admin_update_annotation_path(id: Annotation.first.id), params_guid + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save for guidance only + put admin_update_annotation_path(id: Annotation.first.id), params_guid + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal 'UPDATE', Annotation.first.text, "expected the record to have been updated" + # valid save for example only + put admin_update_annotation_path(id: Annotation.first.id), params_example + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal 'UPDATE', Annotation.first.text, "expected the record to have been updated" + # valid save for both example answer and guidance + put admin_update_annotation_path(id: Annotation.first.id), params_both + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true&question_id=#{@question.id}§ion_id=#{@question.section.id}" + assert_equal 'gUPDATE', Annotation.first.text, "expected the record to have been updated" + assert_equal 'eUPDATE', Annotation.last.text, "expected the record to have been updated" + + end + + # DELETE /org/admin/templates/suggested_answers/:id/admin_destroy (admin_destroy_suggested_answer_path) + # ---------------------------------------------------------- + test "delete the section" do + id = Annotation.first.id + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_annotation_path(id: id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_annotation_path(id: id) + assert_equal _('Information was successfully deleted.'), flash[:notice] + assert_response :redirect + assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?edit=true§ion_id=#{@question.section.id}" + assert assigns(:question) + assert assigns(:section) + assert assigns(:phase) + assert_raise ActiveRecord::RecordNotFound do + Annotation.find(id).nil? + end + end + +end \ No newline at end of file diff --git a/test/functional/answers_controller_test.rb b/test/functional/answers_controller_test.rb index 9981abc..a659295 100644 --- a/test/functional/answers_controller_test.rb +++ b/test/functional/answers_controller_test.rb @@ -1,51 +1,79 @@ -require 'test_helper' - -class AnswersControllerTest < ActionController::TestCase -=begin - setup do - @answer = answers(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:answers) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create answer" do - assert_difference('Answer.count') do - post :create, answer: { text: @answer.text, plan_id: @answer.plan_id, question_id: @answer.question_id, user_id: @answer.user_id } - end - - assert_redirected_to answer_path(assigns(:answer)) - end - - test "should show answer" do - get :show, id: @answer - assert_response :success - end - - test "should get edit" do - get :edit, id: @answer - assert_response :success - end - - test "should update answer" do - put :update, id: @answer, answer: { text: @answer.text, plan_id: @answer.plan_id, question_id: @answer.question_id, user_id: @answer.user_id } - assert_redirected_to answer_path(assigns(:answer)) - end - - test "should destroy answer" do - assert_difference('Answer.count', -1) do - delete :destroy, id: @answer - end - - assert_redirected_to answers_path - end -=end -end +require 'test_helper' + +class AnswersControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @user = User.last + + scaffold_plan + end + + # PUT/PATCH /[:locale]/answer/[:id] + # ---------------------------------------------------------- + test "should be able to update an answer" do + sign_in @user + + # Test an answer for each Querstion Format + QuestionFormat.all.each do |format| + question = Question.find_by(question_format: format) + template = question.section.phase.template + + plan = Plan.create(title: "Testing Answer For #{format.title}", + template: template) + + Role.create!(user_id: @user.id, plan_id: plan.id, access: 4) + plan.reload + + referrer = "/#{FastGettext.locale}/plans/#{plan.id}/phases/#{question.section.phase.id}/edit" + + if format.option_based + + else + # Try creating one first + form_attributes = { + answer: {user_id: @user.id, + plan_id: plan.id, + question_id: question.id, + text: "#{format.title} Tester", + lock_version: 0} + } + + put_answer(Answer.new(), form_attributes, referrer) + + answer = Answer.find_by(user: @user, plan: plan, question: question) + assert_not answer.id.nil?, "expected the answer to have been created and for an id to be present after creating a #{format.title} question!" + + # Try editing it + form_attributes = { + answer: {id: answer.id, + user_id: answer.user.id, + plan_id: answer.plan.id, + question_id: answer.question.id, + text: "Tested", + lock_version: answer.lock_version} + } + + put_answer(answer, form_attributes, referrer) + + answer.reload + + assert_not answer.id.nil?, "expected the answer to have been updated and for an id to be present after creating a #{format.title} question!" + assert_equal "Tested", answer.text, "expected the text to have been updated for a #{format.title} question!" + + end + end + end + + + private + def put_answer(answer, attributes, referrer) + put answer_path(FastGettext.locale, answer, format: "js"), attributes, {'HTTP_REFERER': referrer} + + assert_response :success + assert_equal "text/javascript", @response.content_type + + assert_match(/[^\$]*\$\("#answer-locking-[0-9]+"\).html\(""\);[^\$]*\$\("#answer-form-[0-9]+"\)[^\.]*.html\(".+"\);[^\$]*\$\("#answer-status-[0-9]+"\)[^.]*.html\(".+"\);[^\$]*\$.[^$]*\$.[^\$]*\$\(".progress"\).html\(".+"\);[^\$]*\$\("#section-progress-[0-9]+"\)[^.]*.html\(".+"\);/, @response.body) + end +end diff --git a/test/functional/api_projects_controller_test.rb b/test/functional/api_projects_controller_test.rb deleted file mode 100644 index 66160b5..0000000 --- a/test/functional/api_projects_controller_test.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'test_helper' -#require "rack/test" - -class ApiProjectsControllerTest < ActionDispatch::IntegrationTest - #include Rack::Test::Methods - - @controller = Api::V0::ProjectsController.new - - test "create validates that a user has plans auth" do -=begin - # has auth for projects - @user = users.first - post '/create', params: {template:{ - organisation: "Arts and Humanities Research Council"}, - project:{title:"my project", email:"org_admin@example.com"}} - assert_response :success - - # has no auth for projects - # @user = users(:user_three) - # post :create, params: {template:{organisation: "Arts and Humanities Research Council"},project:{title:"my project", email:"org_admin@example.com"}} - # assert_response 400 -=end - end - - test "create validates that the passed organisation exists" do - - end - - test "create validates that the passed organisation is a funder" do - - end - - test "create validates that the passed organisation has only 1 template" do - - end - - test "create validates that a passed organisation with more than one template specifies template" do - - end - - test "create checks for a guidance and adds it if it exists" do - - end - - test "create checks for guidances and adds them if they exist" do - - end - - test "create invites is user email not already in system" do - - end - - test "create creates a new project when params correct" do - - end - -end \ No newline at end of file diff --git a/test/functional/application_controller_test.rb b/test/functional/application_controller_test.rb new file mode 100644 index 0000000..5af6367 --- /dev/null +++ b/test/functional/application_controller_test.rb @@ -0,0 +1,67 @@ +require 'test_helper' + +class ApplicationControllerTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + @user = User.first + + stub_blog_calls + + scaffold_plan + end + + # In order to test methods on the application controller, we must call routes + # on controllers that extend the ApplicationController class. + + # ---------------------------------------------------------------- + test "make sure unauthorized users are redirected to the root path" do + plan = Plan.first + get plan_path(plan) + + assert_redirected_to "#{root_path}" + end + + # ---------------------------------------------------------------- + test "a user's language specification gets picked up and set in the session" do + if LANGUAGES.count > 1 + @user.language = LANGUAGES.last + @user.save! + + sign_in @user + + get root_path + + # TODO: Setting the User's language doesn't seem to update the locale in this context but it probably should! + #assert_equal @user.language.abbreviation, FastGettext.locale, "Expected the locale to have been set to the user's chosen language" + end + end + + # ---------------------------------------------------------------- + test "a user's org language specification gets picked up and used if the user has no language setting" do + if LANGUAGES.count > 1 + @user.language = nil + + @user.org[:language_id] = LANGUAGES.last.id + @user.save! + + sign_in @user + + get root_path + org_lang = Language.find(@user.org[:language_id]) + # TODO: Setting the Org's language doesn't seem to update the locale in this context but it probably should! + #assert_equal org_lang.abbreviation, FastGettext.locale, "Expected the locale to have been set to the org's chosen language" + end + end + + # ---------------------------------------------------------------- + test "the last visited url is stored in the session" do + get root_path + assert_equal root_path, session[:previous_url] + + sign_in @user + get plans_path + assert_equal plans_path, session[:previous_url] + end + +end diff --git a/test/functional/dmptemplates_controller_test.rb b/test/functional/dmptemplates_controller_test.rb deleted file mode 100644 index a3a7521..0000000 --- a/test/functional/dmptemplates_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class DmptemplatesControllerTest < ActionController::TestCase -=begin - setup do - @dmptemplate = dmptemplates(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:dmptemplates) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create dmptemplate" do - assert_difference('Dmptemplate.count') do - post :create, dmptemplate: { organisation_id: @dmptemplate.organisation_id, description: @dmptemplate.description, published: @dmptemplate.published, title: @dmptemplate.title, user_id: @dmptemplate.user_id } - end - - assert_redirected_to dmptemplate_path(assigns(:dmptemplate)) - end - - test "should show dmptemplate" do - get :show, id: @dmptemplate - assert_response :success - end - - test "should get edit" do - get :edit, id: @dmptemplate - assert_response :success - end - - test "should update dmptemplate" do - put :update, id: @dmptemplate, dmptemplate: { organisation_id: @dmptemplate.organisation_id, description: @dmptemplate.description, published: @dmptemplate.published, title: @dmptemplate.title, user_id: @dmptemplate.user_id } - assert_redirected_to dmptemplate_path(assigns(:dmptemplate)) - end - - test "should destroy dmptemplate" do - assert_difference('Dmptemplate.count', -1) do - delete :destroy, id: @dmptemplate - end - - assert_redirected_to dmptemplates_path - end -=end -end diff --git a/test/functional/file_types_controller_test.rb b/test/functional/file_types_controller_test.rb deleted file mode 100644 index 168c370..0000000 --- a/test/functional/file_types_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class FileTypesControllerTest < ActionController::TestCase -=begin - setup do - @file_type = file_types(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:file_types) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create file_type" do - assert_difference('FileType.count') do - post :create, file_type: { name: @file_type.name, icon_location: @file_type.icon_location, icon_name: @file_type.icon_name, icon_size: @file_type.icon_size } - end - - assert_redirected_to file_type_path(assigns(:file_type)) - end - - test "should show file_type" do - get :show, id: @file_type - assert_response :success - end - - test "should get edit" do - get :edit, id: @file_type - assert_response :success - end - - test "should update file_type" do - put :update, id: @file_type, file_type: { name: @file_type.name, icon_location: @file_type.icon_location, icon_name: @file_type.icon_name, icon_size: @file_type.icon_size } - assert_redirected_to file_type_path(assigns(:file_type)) - end - - test "should destroy file_type" do - assert_difference('FileType.count', -1) do - delete :destroy, id: @file_type - end - - assert_redirected_to file_types_path - end -=end -end diff --git a/test/functional/file_uploads_controller_test.rb b/test/functional/file_uploads_controller_test.rb deleted file mode 100644 index 41a1a64..0000000 --- a/test/functional/file_uploads_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class FileUploadsControllerTest < ActionController::TestCase -=begin - setup do - @file_upload = file_uploads(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:file_uploads) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create file_upload" do - assert_difference('FileUpload.count') do - post :create, file_upload: { file_type_id: @file_upload.file_type_id, description: @file_upload.description, location: @file_upload.location, name: @file_upload.name, published: @file_upload.published, size: @file_upload.size, title: @file_upload.title } - end - - assert_redirected_to file_upload_path(assigns(:file_upload)) - end - - test "should show file_upload" do - get :show, id: @file_upload - assert_response :success - end - - test "should get edit" do - get :edit, id: @file_upload - assert_response :success - end - - test "should update file_upload" do - put :update, id: @file_upload, file_upload: { file_type_id: @file_upload.file_type_id, description: @file_upload.description, location: @file_upload.location, name: @file_upload.name, published: @file_upload.published, size: @file_upload.size, title: @file_upload.title } - assert_redirected_to file_upload_path(assigns(:file_upload)) - end - - test "should destroy file_upload" do - assert_difference('FileUpload.count', -1) do - delete :destroy, id: @file_upload - end - - assert_redirected_to file_uploads_path - end -=end -end diff --git a/test/functional/guidance_groups_controller_test.rb b/test/functional/guidance_groups_controller_test.rb new file mode 100644 index 0000000..a8d75fb --- /dev/null +++ b/test/functional/guidance_groups_controller_test.rb @@ -0,0 +1,143 @@ +require 'test_helper' + +class GuidanceGroupsControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + # TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has + # these defined. They are defined multiple times though and we need to clean this up! In particular + # look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates. + # We should just have: + # + # SHOULD BE: + # -------------------------------------------------- + # guidance_groups GET /guidance_groups guidance_groups#index + # POST /guidance_groups guidance_groups#create + # guidance_group GET /guidance_group/:id guidance_groups#show + # PATCH /guidance_groups/:id guidance_groups#update + # PUT /guidance_groups/:id guidance_groups#update + # DELETE /guidance_groups/:id guidance_groups#destroy + # + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # admin_show_guidance_group GET /org/admin/guidancegroup/:id/admin_show guidance_groups#admin_show + # admin_new_guidance_group GET /org/admin/guidancegroup/:id/admin_new guidance_groups#admin_new + # admin_edit_guidance_group GET /org/admin/guidancegroup/:id/admin_edit guidance_groups#admin_edit + # admin_destroy_guidance_group DELETE /org/admin/guidancegroup/:id/admin_destroy guidance_groups#admin_destroy + # admin_create_guidance_group POST /org/admin/guidancegroup/:id/admin_create guidance_groups#admin_create + # admin_update_guidance_group PUT /org/admin/guidancegroup/:id/admin_update guidance_groups#admin_update + + setup do + scaffold_org_admin(GuidanceGroup.first.org) + end + + # GET /org/admin/guidancegroup/:id/admin_show (admin_show_guidance_group_path) + # ---------------------------------------------------------- + test 'show the guidance_group' do + # Should redirect user to the root path if they are not logged in! + get admin_show_guidance_group_path(GuidanceGroup.find_by(org: @user.org)) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_show_guidance_group_path(GuidanceGroup.find_by(org: @user.org)) + assert_response :success + end + + # GET /org/admin/guidancegroup/:id/admin_new (admin_new_guidance_group_path) + # ---------------------------------------------------------- + test 'load the new guidance_group page' do + # Should redirect user to the root path if they are not logged in! + # TODO: Why is there an id here!? its a new guidance_group! + get admin_new_guidance_group_path(@user.org) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_new_guidance_group_path(@user.org) + assert_response :success + end + + # POST /org/admin/guidancegroup/:id/admin_create (admin_create_guidance_group_path) + # ---------------------------------------------------------- + test 'create a new guidance_group' do + params = {org_id: @user.org.id, published: false, name: 'Testing create'} + + # Should redirect user to the root path if they are not logged in! + post admin_create_guidance_group_path(@user.org), {guidance_group: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post admin_create_guidance_group_path(@user.org), {guidance_group: params} + assert_response :redirect + assert_redirected_to admin_index_guidance_path(@user.org) + assert_equal _('Guidance group was successfully created.'), flash[:notice] + assert assigns(:guidance_group) + assert_equal 'Testing create', GuidanceGroup.last.name, "expected the record to have been created!" + + # Invalid object + post admin_create_guidance_group_path(@user.org), {guidance_group: {name: nil}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:guidance_group) + end + + # GET /org/admin/guidancegroup/:id/admin_edit (admin_edit_guidance_group_path) + # ---------------------------------------------------------- + test 'load the edit guidance_group page' do + # Should redirect user to the root path if they are not logged in! + get admin_edit_guidance_group_path(GuidanceGroup.find_by(org: @user.org)) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_edit_guidance_group_path(GuidanceGroup.find_by(org: @user.org)) + assert_response :success + end + + # PUT /org/admin/templates/:id/admin_template (admin_update_guidance_group_path) + # ---------------------------------------------------------- + test 'update the guidance_group' do + params = {name: 'Testing UPDATE'} + + # Should redirect user to the root path if they are not logged in! + put admin_update_guidance_group_path(GuidanceGroup.first), {guidance_group: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + put admin_update_guidance_group_path(GuidanceGroup.first), {guidance_group: params} + assert_equal _('Guidance group was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to "#{admin_index_guidance_path(@user.org)}?name=Testing+UPDATE" + assert assigns(:guidance_group) + assert_equal 'Testing UPDATE', GuidanceGroup.first.name, "expected the record to have been updated" + + # Invalid object + put admin_update_guidance_group_path(GuidanceGroup.first), {guidance_group: {name: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:guidance_group) + end + + # DELETE /org/admin/guidancegroup/:id/admin_destroy (admin_destroy_guidance_group_path) + # ---------------------------------------------------------- + test 'delete the guidance_group' do + id = GuidanceGroup.first.id + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_guidance_group_path(GuidanceGroup.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_guidance_group_path(GuidanceGroup.first) + assert_response :redirect + assert_redirected_to admin_index_guidance_path + assert_equal _('Guidance group was successfully deleted.'), flash[:notice] + assert_raise ActiveRecord::RecordNotFound do + GuidanceGroup.find(id).nil? + end + end + +end \ No newline at end of file diff --git a/test/functional/guidances_controller_test.rb b/test/functional/guidances_controller_test.rb index 2dc60d1..144bc71 100644 --- a/test/functional/guidances_controller_test.rb +++ b/test/functional/guidances_controller_test.rb @@ -1,51 +1,170 @@ -require 'test_helper' - -class GuidancesControllerTest < ActionController::TestCase -=begin - setup do - @guidance = guidances(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:guidances) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create guidance" do - assert_difference('Guidance.count') do - post :create, guidance: { file_id: @guidance.file_id, text: @guidance.text, organisation_id: @guidance.organisation_id, theme_id: @guidance.theme_id } - end - - assert_redirected_to guidance_path(assigns(:guidance)) - end - - test "should show guidance" do - get :show, id: @guidance - assert_response :success - end - - test "should get edit" do - get :edit, id: @guidance - assert_response :success - end - - test "should update guidance" do - put :update, id: @guidance, guidance: { file_id: @guidance.file_id, text: @guidance.text, organisation_id: @guidance.organisation_id, theme_id: @guidance.theme_id } - assert_redirected_to guidance_path(assigns(:guidance)) - end - - test "should destroy guidance" do - assert_difference('Guidance.count', -1) do - delete :destroy, id: @guidance - end - - assert_redirected_to guidances_path - end -=end -end +require 'test_helper' + +class GuidancesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + # TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has + # these defined. They are defined multiple times though and we need to clean this up: + # + # SHOULD BE: + # -------------------------------------------------- + # guidances GET /guidances guidances#index + # POST /guidances guidances#create + # guidance GET /guidance/:id guidances#show + # PATCH /guidance/:id guidances#update + # PUT /guidance/:id guidances#update + # DELETE /guidance/:id guidances#destroy + # + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # admin_show_guidance GET /org/admin/guidance/:id/admin_show guidances#admin_show + # admin_index_guidance GET /org/admin/guidance/:id/admin_index guidances#admin_index + # admin_edit_guidance GET /org/admin/guidance/:id/admin_edit guidances#admin_edit + # admin_new_guidance GET /org/admin/guidance/:id/admin_new guidances#admin_new + # admin_destroy_guidance DELETE /org/admin/guidance/:id/admin_destroy guidances#admin_destroy + # admin_create_guidance POST /org/admin/guidance/:id/admin_create guidances#admin_create + # admin_update_guidance PUT /org/admin/guidance/:id/admin_update guidances#admin_update + # update_phases_guidance GET /org/admin/guidance/:id/update_phases guidances#update_phases + # update_versions_guidance GET /org/admin/guidance/:id/update_versions guidances#update_versions + # update_sections_guidance GET /org/admin/guidance/:id/update_sections guidances#update_sections + # update_questions_guidance GET /org/admin/guidance/:id/update_questions guidances#update_questions + + setup do + scaffold_org_admin(GuidanceGroup.first.org) + @guidance_group = GuidanceGroup.first + end + + # GET /org/admin/guidance/:id/admin_index (admin_index_guidance_path) + # ---------------------------------------------------------- + test 'load the list of guidances page' do + # Should redirect user to the root path if they are not logged in! + get admin_index_guidance_path(@guidance_group) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_index_guidance_path(@guidance_group) + assert_response :success + assert assigns(:guidances) + assert assigns(:guidance_groups) + end + + # GET /org/admin/guidance/:id/admin_show (admin_show_guidance_path) + # ---------------------------------------------------------- + test 'load the guidance page' do + # Should redirect user to the root path if they are not logged in! + # TODO: Why is there an id here!? its a new guidance_group! + get admin_show_guidance_path(guidance_group_id: @guidance_group.id, id: @guidance_group.guidances.first.id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_show_guidance_path(guidance_group_id: @guidance_group.id, id: @guidance_group.guidances.first.id) + assert_response :success + assert assigns(:guidance) + end + + # /org/admin/guidance/:id/admin_new (admin_new_guidance_path) + # ---------------------------------------------------------- + test 'load the new guidance page' do + # Should redirect user to the root path if they are not logged in! + get admin_new_guidance_path(@guidance_group) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_new_guidance_path(@guidance_group) + assert_response :success + assert assigns(:guidance) + assert assigns(:guidance_groups) + assert assigns(:themes) + end + + # /org/admin/guidance/:id/admin_edit (admin_edit_guidance_path) + # ---------------------------------------------------------- + test 'load the edit guidance page' do + # Should redirect user to the root path if they are not logged in! + get admin_edit_guidance_path(@guidance_group) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_edit_guidance_path(@guidance_group) + assert_response :success + assert assigns(:guidance) + assert assigns(:guidance_groups) + assert assigns(:themes) + end + + # POST /org/admin/guidance/:id/admin_create (admin_create_guidance_path) + # ---------------------------------------------------------- + test 'create a new guidance' do + params = {'guidance-text': 'Testing create', guidance: {guidance_group_id: GuidanceGroup.first.id, published: true}} + + # Should redirect user to the root path if they are not logged in! + post admin_create_guidance_path(@user.org), params + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post admin_create_guidance_path(@user.org), params + assert_response :redirect + assert_redirected_to admin_show_guidance_path(Guidance.last) + assert_equal _('Guidance was successfully created.'), flash[:notice] + assert assigns(:guidance) + assert_equal 'Testing create', Guidance.last.text, "expected the record to have been created!" + + # Invalid object + post admin_create_guidance_path(@user.org), {'guidance-text': nil, guidance: {published: false}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:guidance) + end + + # PUT /org/admin/guidance/:id/admin_update (admin_update_guidance_path) + # ---------------------------------------------------------- + test 'update the guidance' do + params = {'guidance-text': 'Testing UPDATE', guidance: {guidance_group_id: GuidanceGroup.first.id}} + + # Should redirect user to the root path if they are not logged in! + put admin_update_guidance_path(Guidance.first), params + assert_unauthorized_redirect_to_root_path + + sign_in @user + + put admin_update_guidance_path(Guidance.first), params + assert_response :redirect + assert_equal _('Guidance was successfully updated.'), flash[:notice] + assert_redirected_to "#{admin_show_guidance_path(Guidance.first)}?guidance_group_id=#{GuidanceGroup.first.id}" + assert assigns(:guidance) + assert_equal 'Testing UPDATE', Guidance.first.text, "expected the record to have been updated" + + # Invalid object + put admin_update_guidance_path(Guidance.first), {'guidance-text': nil, guidance: {guidance_group_id: GuidanceGroup.first.id}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:guidance) + end + + # DELETE /org/admin/guidance/:id/admin_destroy (admin_destroy_guidance_path) + # ---------------------------------------------------------- + test 'delete the guidance' do + id = Guidance.first.id + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_guidance_path(Guidance.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_guidance_path(Guidance.first) + assert_response :redirect + assert_redirected_to admin_index_guidance_path + assert_equal _('Guidance was successfully deleted.'), flash[:notice] + assert assigns(:guidance) + assert_raise ActiveRecord::RecordNotFound do + Guidance.find(id).nil? + end + end + +end \ No newline at end of file diff --git a/test/functional/home_controller_test.rb b/test/functional/home_controller_test.rb index d088a29..a585c99 100644 --- a/test/functional/home_controller_test.rb +++ b/test/functional/home_controller_test.rb @@ -1,10 +1,40 @@ -require 'test_helper' - -class HomeControllerTest < ActionController::TestCase -=begin - test "should get index" do - get :index - assert_response :success - end -=end -end +require 'test_helper' + +class HomeControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @user = User.create(email: 'testing.another@user.account.org', password: 'password123', + password_confirmation: 'password123', accept_terms: true, + confirmed_at: Time.zone.now) + end + + # ---------------------------------------------------------- + test 'redirects logged in user to plans page' do + @user.firstname = 'Testing' + @user.surname = 'Another' + @user.save! + + sign_in @user + + get root_path + assert_response :redirect + assert_redirected_to plans_url + end + + # ---------------------------------------------------------- + test 'redirects logged in user to profile page if they have not added their name' do + sign_in @user + + get root_path + assert_response :redirect + +# TODO: This should be redirecting to the profile page so that the user can provide their name but the logic +# in the User model will always return the email address as the name so the check in the controller +# is always true and sends the user through to the plans page + #assert_redirected_to edit_user_registration_path + assert_redirected_to plans_url + end + +end \ No newline at end of file diff --git a/test/functional/notes_controller_test.rb b/test/functional/notes_controller_test.rb new file mode 100644 index 0000000..65bc55a --- /dev/null +++ b/test/functional/notes_controller_test.rb @@ -0,0 +1,151 @@ +require 'test_helper' + +class NotesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @user = User.last + + scaffold_plan + + @question = Question.create(text: 'Answer Testing', number: 9, + section: @plan.template.phases.first.sections.first, + question_format: QuestionFormat.find_by(option_based: false)) + + @answer = Answer.create(user: @user, plan: @plan, question: @question, text: 'Testing') + + @note = Note.create(user: @user, plan: @plan, answer: @answer, question: @question, archived: false, + text: 'Test Note') + end + +# TODO: The following methods SHOULD probably be restful +# +# SHOULD BE: +# -------------------------------------------------- +# notes GET /answers/:answer_id/notes notes#index +# POST /answers/:answer_id/notes notes#create +# note GET /answers/:answer_id/notes/:id notes#show +# PATCH /answers/:answer_id/notes/:id notes#update +# PUT /answers/:answer_id/notes/:id notes#update +# DELETE /answers/:answer_id/notes/:id notes#destroy +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# archive_note PATCH /notes/:id/archive notes#archive +# notes POST /notes notes#create +# note PATCH /notes/:id notes#update +# PUT /notes/:id notes#update + + + + # POST /notes (notes_path) + # ---------------------------------------------------------- + test "create a new note" do + params = {user_id: @user.id, answer_id: @answer.id, plan_id: @plan.id, question_id: @question.id, + "#{@question.id}new_note_text": 'Test Note'} + + # Should redirect user to the root path if they are not logged in! + post notes_path, {new_note: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post notes_path, {new_note: params}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) + assert assigns(:num_notes) +# TODO: We don't appear to be displaying the success/failure notice anywhere in the js.erb + #assert_select '.welcome-message h2', _('Comment was successfully created.') + assert_equal 'Test Note', Note.last.text, 'Expected the note to have been created' + + # No Answer + post notes_path, {new_note: {user_id: @user.id, plan_id: @plan.id, question_id: @question.id, + "#{@question.id}new_note_text": 'Test Note no Answer'}}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) + assert assigns(:num_notes) +# TODO: We don't appear to be displaying the success/failure notice anywhere in the js.erb + #assert_select '.welcome-message h2', _('Comment was successfully created.') +# TODO: expected the new note to have been added :/ + #assert_equal 'Test Note no Answer', Note.last.text, 'Expected the note to have been created even if there was no answer' + + # Invalid object + post notes_path, {new_note: {user_id: @user.id, answer_id: @answer.id, plan_id: @plan.id, + question_id: @question.id}}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) + assert assigns(:num_notes) +# TODO: We don't appear to be displaying the success/failure notice anywhere in the js.erb + #assert_select '.welcome-message h2', _('Unable to save your changes.') + end + + # PUT /notes/:id (note_path) + # ---------------------------------------------------------- + test "update the note" do + # Should redirect user to the root path if they are not logged in! + put note_path(@note), {note: {id: @note.id}, "#{@question.id}new_note_text": 'Test Note'}, {'ACCEPT': 'text/javascript'} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put note_path(@note), {note: {id: @note.id}, "#{@question.id}new_note_text": 'Test Note'}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) +# TODO: We don't appear to be displaying the success/failure notice anywhere in the js.erb + #assert_select '.welcome-message h2', _('Comment was successfully created.') + @note.reload + assert_equal 'Test Note', @note.text, "expected the note's text to be 'Test Note'" + + # Invalid save + put note_path(@note), {note: {id: @note.id}, "#{@question.id}new_note_text": nil}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) +# TODO: We don't appear to be displaying the success/failure notice anywhere in the js.erb + #assert_select '.welcome-message h2', _('Unable to save your changes.') + assert_equal 'Test Note', @note.text, "expected the note's text to Still be 'Test Note'" + end + + # PATCH /notes/:id/archive (archive_note_path) + # ---------------------------------------------------------- + test "delete the note" do + # Should redirect user to the root path if they are not logged in! + patch archive_note_path(@note), {note: {id: @note.id, archived_by: @user.id}}, {'ACCEPT': 'text/javascript'} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + patch archive_note_path(@note), {note: {id: @note.id, archived_by: @user.id}}, {'ACCEPT': 'text/javascript'} + assert_response :success + assert assigns(:note) + assert assigns(:plan) + assert assigns(:answer) + assert assigns(:question) + assert assigns(:notice) + + @note.reload + assert @note.archived, 'expected the archived flag to be true' + assert_equal @user.id, @note.archived_by, 'expected the archived_by to be set to @user' + end +end \ No newline at end of file diff --git a/test/functional/organisation_types_controller_test.rb b/test/functional/organisation_types_controller_test.rb deleted file mode 100644 index 380dd88..0000000 --- a/test/functional/organisation_types_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class OrganisationTypesControllerTest < ActionController::TestCase -=begin - setup do - @organisation_type = organisation_types(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:organisation_types) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create organisation_type" do - assert_difference('OrganisationType.count') do - post :create, organisation_type: { description: @organisation_type.description, name: @organisation_type.name } - end - - assert_redirected_to organisation_type_path(assigns(:organisation_type)) - end - - test "should show organisation_type" do - get :show, id: @organisation_type - assert_response :success - end - - test "should get edit" do - get :edit, id: @organisation_type - assert_response :success - end - - test "should update organisation_type" do - put :update, id: @organisation_type, organisation_type: { description: @organisation_type.description, name: @organisation_type.name } - assert_redirected_to organisation_type_path(assigns(:organisation_type)) - end - - test "should destroy organisation_type" do - assert_difference('OrganisationType.count', -1) do - delete :destroy, id: @organisation_type - end - - assert_redirected_to organisation_types_path - end -=end -end diff --git a/test/functional/organisations_controller_test.rb b/test/functional/organisations_controller_test.rb deleted file mode 100644 index c43d4f4..0000000 --- a/test/functional/organisations_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class OrganisationsControllerTest < ActionController::TestCase -=begin - setup do - @organisation = organisations(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:organisations) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create organisation" do - assert_difference('Organisation.count') do - post :create, organisation: { abbreviation: @organisation.abbreviation, banner_file_id: @organisation.banner_file_id, description: @organisation.description, domain: @organisation.domain, logo_file_id: @organisation.logo_file_id, name: @organisation.name, stylesheet_file_id: @organisation.stylesheet_file_id, target_url: @organisation.target_url, type_id: @organisation.type_id, wayfless_entite: @organisation.wayfless_entite } - end - - assert_redirected_to organisation_path(assigns(:organisation)) - end - - test "should show organisation" do - get :show, id: @organisation - assert_response :success - end - - test "should get edit" do - get :edit, id: @organisation - assert_response :success - end - - test "should update organisation" do - put :update, id: @organisation, organisation: { abbreviation: @organisation.abbreviation, banner_file_id: @organisation.banner_file_id, description: @organisation.description, domain: @organisation.domain, logo_file_id: @organisation.logo_file_id, name: @organisation.name, stylesheet_file_id: @organisation.stylesheet_file_id, target_url: @organisation.target_url, type_id: @organisation.type_id, wayfless_entite: @organisation.wayfless_entite } - assert_redirected_to organisation_path(assigns(:organisation)) - end - - test "should destroy organisation" do - assert_difference('Organisation.count', -1) do - delete :destroy, id: @organisation - end - - assert_redirected_to organisations_path - end -=end -end diff --git a/test/functional/orgs_controller_test.rb b/test/functional/orgs_controller_test.rb new file mode 100644 index 0000000..803be47 --- /dev/null +++ b/test/functional/orgs_controller_test.rb @@ -0,0 +1,85 @@ +require 'test_helper' + +class OrgsControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + # TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The children_org and templates_org + # routes don't even have an endpoint defined in the controller! + # + # SHOULD BE: + # -------------------------------------------------- + # orgs GET /orgs orgs#index + # POST /orgs orgs#create + # org GET /orgs/:id orgs#show + # PATCH /orgs/:id orgs#update + # PUT /orgs/:id orgs#update + # DELETE /orgs/:id orgs#destroy + # + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # children_org GET /org/admin/:id/children orgs#children + # templates_org GET /org/admin/:id/templates orgs#templates + # admin_show_org GET /org/admin/:id/admin_show orgs#admin_show + # admin_edit_org GET /org/admin/:id/admin_edit orgs#admin_edit + # admin_update_org PUT /org/admin/:id/admin_update orgs#admin_update + + setup do + @org = Org.first + scaffold_org_admin(@org) + end + + # GET /org/admin/:id/admin_show (admin_show_org_path) + # ---------------------------------------------------------- + test 'show the org' do + # Should redirect user to the root path if they are not logged in! + get admin_show_org_path(@org) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_show_org_path(@org) + assert_response :success + assert assigns(:org) + end + + # GET /org/admin/:id/admin_edit (admin_edit_org_path) + # ---------------------------------------------------------- + test 'load the edit org page' do + # Should redirect user to the root path if they are not logged in! + get admin_edit_org_path(@org) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_edit_org_path(@org) + assert_response :success + assert assigns(:org) + assert assigns(:languages) + end + + # PUT /org/admin/:id/admin_update (admin_update_org_path) + # ---------------------------------------------------------- + test 'update the org' do + params = {name: 'Testing UPDATE'} + + # Should redirect user to the root path if they are not logged in! + put admin_update_org_path(@org), {org: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + put admin_update_org_path(@org), {org: params} + assert_equal _('Organisation was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_show_org_path(@org) + assert assigns(:org) + assert_equal 'Testing UPDATE', @org.reload.name, "expected the record to have been updated" + + # Invalid object + put admin_update_org_path(@org), {org: {name: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:org) + end +end diff --git a/test/functional/pages_controller_test.rb b/test/functional/pages_controller_test.rb deleted file mode 100644 index b525098..0000000 --- a/test/functional/pages_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class PagesControllerTest < ActionController::TestCase -=begin - setup do - @page = pages(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:pages) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create page" do - assert_difference('Page.count') do - post :create, page: { organisation_id: @page.organisation_id, body_text: @page.body_text, location: @page.location, menu: @page.menu, menu_position: @page.menu_position, public: @page.public, slug: @page.slug, target_url: @page.target_url, title: @page.title } - end - - assert_redirected_to page_path(assigns(:page)) - end - - test "should show page" do - get :show, id: @page - assert_response :success - end - - test "should get edit" do - get :edit, id: @page - assert_response :success - end - - test "should update page" do - put :update, id: @page, page: { organisation_id: @page.organisation_id, body_text: @page.body_text, location: @page.location, menu: @page.menu, menu_position: @page.menu_position, public: @page.public, slug: @page.slug, target_url: @page.target_url, title: @page.title } - assert_redirected_to page_path(assigns(:page)) - end - - test "should destroy page" do - assert_difference('Page.count', -1) do - delete :destroy, id: @page - end - - assert_redirected_to pages_path - end -=end -end diff --git a/test/functional/phases_controller_test.rb b/test/functional/phases_controller_test.rb index b392886..3cd91b5 100644 --- a/test/functional/phases_controller_test.rb +++ b/test/functional/phases_controller_test.rb @@ -1,51 +1,235 @@ -require 'test_helper' - -class PhasesControllerTest < ActionController::TestCase -=begin - setup do - @phase = phases(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:phases) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create phase" do - assert_difference('Phase.count') do - post :create, phase: { description: @phase.description, order: @phase.order, title: @phase.title } - end - - assert_redirected_to phase_path(assigns(:phase)) - end - - test "should show phase" do - get :show, id: @phase - assert_response :success - end - - test "should get edit" do - get :edit, id: @phase - assert_response :success - end - - test "should update phase" do - put :update, id: @phase, phase: { description: @phase.description, order: @phase.order, title: @phase.title } - assert_redirected_to phase_path(assigns(:phase)) - end - - test "should destroy phase" do - assert_difference('Phase.count', -1) do - delete :destroy, id: @phase - end - - assert_redirected_to phases_path - end -=end -end +require 'test_helper' + +class PhasesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + + # Get the first Org Admin + scaffold_org_admin(@template.org) + + @plan = Plan.create!(template: @template, title: 'Test Plan', + roles: [Role.new(user: @user, creator: true)]) + end + +# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has +# these defined. They are defined multiple times though and we need to clean this up! In particular +# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates. +# We should just have: +# +# SHOULD BE: +# -------------------------------------------------- +# phases GET /templates/:template_id/phases phases#index +# POST /templates/:template_id/phases phases#create +# phase GET /templates/:template_id/phase/:id phases#show +# PATCH /templates/:template_id/phase/:id phases#update +# PUT /templates/:template_id/phase/:id phases#update +# DELETE /templates/:template_id/phase/:id phases#destroy +# edit_phase GET /templates/:template_id/phase/:id/edit phases#edit +# new_phase GET /templates/:template_id/phase/new phases#new +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# admin_show_phase GET /org/admin/templates/phases/:id/admin_show(.:format) phases#admin_show +# admin_preview_phase GET /org/admin/templates/phases/:id/admin_preview(.:format) phases#admin_preview +# admin_add_phase GET /org/admin/templates/phases/:id/admin_add(.:format) phases#admin_add +# admin_update_phase PUT /org/admin/templates/phases/:id/admin_update(.:format) phases#admin_update +# admin_create_phase POST /org/admin/templates/phases/:id/admin_create(.:format) phases#admin_create +# admin_destroy_phase DELETE /org/admin/templates/phases/:id/admin_destroy(.:format) phases#admin_destroy +# +# edit_plan_phase GET /plans/:plan_id/phases/:id/edit(.:format) phases#edit +# status_plan_phase GET /plans/:plan_id/phases/:id/status(.:format) phases#status +# plan_phase POST /plans/:plan_id/phases/:id/update(.:format) phases#update +# plan_phases GET /plans/:plan_id/phases(.:format) phases#index +# POST /plans/:plan_id/phases(.:format) phases#create +# new_plan_phase GET /plans/:plan_id/phases/new(.:format) phases#new +# GET /plans/:plan_id/phases/:id/edit(.:format) phases#edit +# GET /plans/:plan_id/phases/:id(.:format) phases#show +# PATCH /plans/:plan_id/phases/:id(.:format) phases#update +# PUT /plans/:plan_id/phases/:id(.:format) phases#update +# DELETE /plans/:plan_id/phases/:id(.:format) phases#destroy + + + + # GET /plans/:plan_id/phases/:id/edit (edit_plan_phase_path) + # ---------------------------------------------------------- + test "show the edit phase page" do + # Should redirect user to the root path if they are not logged in! + get edit_plan_phase_path(@plan, @template.phases.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # TODO: Why does the policy check fail when @user is the creator and owner of @plan!? + # Trying `@plan.assign_editor(@user)` doesn't work either! + #get edit_plan_phase_path(@plan, @template.phases.first) + #assert_response :success + + #assert assigns(:plan) + #assert assigns(:phase) + #assert assigns(:question_guidance) + end + + # GET /plans/:plan_id/phases/:id/status (status_plan_phase_path) + # ---------------------------------------------------------- + test "get the phase's status" do + # Should redirect user to the root path if they are not logged in! + get status_plan_phase_path(plan_id: @plan.id, id: @template.phases.first.id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get status_plan_phase_path(@plan, @template.phases.first), format: :json + assert_response :success + + assert assigns(:plan) + end + +# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id + # GET /org/admin/templates/phases/:id/admin_show (admin_show_phase_path) + # ---------------------------------------------------------- + test "show the phase" do + # Should redirect user to the root path if they are not logged in! + get admin_show_phase_path(@template.phases.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_show_phase_path(@template.phases.first) + assert_response :success + + assert assigns(:phase) + #assert assigns(:edit) + assert assigns(:sections) + end + + # GET /org/admin/templates/phases/:id/admin_preview (admin_preview_phase_path) + # ---------------------------------------------------------- + test "preview the phase" do + # Should redirect user to the root path if they are not logged in! + get admin_preview_phase_path(@template.phases.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_preview_phase_path(@template.phases.first) + assert_response :success + + assert assigns(:template) + assert assigns(:phase) + end + + # GET /org/admin/templates/phases/:id/admin_add (admin_add_phase) Why do we have an id here!? + # ---------------------------------------------------------- + test "show the new phase page" do + # Should redirect user to the root path if they are not logged in! + get admin_add_phase_path(@template.id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_add_phase_path(@template.id) + assert_response :success + + assert assigns(:template) + assert assigns(:phase) + end + +# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id + # POST /org/admin/templates/phases/:id/admin_create (admin_create_phase_path) + # ---------------------------------------------------------- + test "create a phase " do + params = {template_id: @template.id, title: 'Phase: Tester 2', number: 2} + + @template.dirty = false + @template.save! + + # Should redirect user to the root path if they are not logged in! + post admin_create_phase_path(@template.phases.first), {phase: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post admin_create_phase_path(@template.phases.first), {phase: params} + assert_equal _('Information was successfully created.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_show_phase_path(id: Phase.last.id, edit: 'true') + assert assigns(:phase) + assert_equal 'Phase: Tester 2', Phase.last.title, "expected the record to have been created!" + + # Make sure that the template's dirty flag got set + assert @template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid object + post admin_create_phase_path(@template.phases.first), {phase: {template_id: @template.id}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:phase) + assert assigns(:template) + end + + # PUT /org/admin/templates/phases/:id/admin_update (admin_update_phase_path) + # ---------------------------------------------------------- + test "update the phase" do + params = {title: 'Phase - UPDATE'} + + @template.dirty = false + @template.save! + + # Should redirect user to the root path if they are not logged in! + put admin_update_phase_path(@template.phases.first), {phase: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put admin_update_phase_path(@template.phases.first), {phase: params} + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_show_phase_url(@template.phases.first) + assert assigns(:phase) + assert_equal 'Phase - UPDATE', @template.phases.first.title, "expected the record to have been updated" + + # Make sure that the template's dirty flag got set + assert @template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid save + put admin_update_phase_path(@template.phases.first), {phase: {title: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:phase) + assert assigns(:template) + assert assigns(:sections) + assert assigns(:edit) + end + + # DELETE /org/admin/templates/phases/:id/admin_destroy (admin_destroy_phase_path) + # ---------------------------------------------------------- + test "delete the phase" do + id = @template.phases.first.id + + @template.dirty = false + @template.save! + + # Should redirect user to the root path if they are not logged in! + # TODO: Why are we not just using id: here? shouldn't need to specify the key + delete admin_destroy_phase_path(id: @template.phases.first.id, phase_id: id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_phase_path(id: @template.phases.first.id, phase_id: id) + assert_response :redirect + assert_redirected_to admin_template_template_path(@template) + assert_equal _('Information was successfully deleted.'), flash[:notice] + assert_raise ActiveRecord::RecordNotFound do + Phase.find(id).nil? + end + + # Make sure that the template's dirty flag got set + assert @template.reload.dirty?, "expected the templates dirty flag to be true" + end + +end diff --git a/test/functional/plan_sections_controller_test.rb b/test/functional/plan_sections_controller_test.rb deleted file mode 100644 index 97bbe62..0000000 --- a/test/functional/plan_sections_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class PlanSectionsControllerTest < ActionController::TestCase -=begin - setup do - @plan_section = plan_sections(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:plan_sections) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create plan_section" do - assert_difference('PlanSection.count') do - post :create, plan_section: { plan_id: @plan_section.plan_id, at: @plan_section.at, edit: @plan_section.edit, section_id: @plan_section.section_id, user_editing_id: @plan_section.user_editing_id } - end - - assert_redirected_to plan_section_path(assigns(:plan_section)) - end - - test "should show plan_section" do - get :show, id: @plan_section - assert_response :success - end - - test "should get edit" do - get :edit, id: @plan_section - assert_response :success - end - - test "should update plan_section" do - put :update, id: @plan_section, plan_section: { plan_id: @plan_section.plan_id, at: @plan_section.at, edit: @plan_section.edit, section_id: @plan_section.section_id, user_editing_id: @plan_section.user_editing_id } - assert_redirected_to plan_section_path(assigns(:plan_section)) - end - - test "should destroy plan_section" do - assert_difference('PlanSection.count', -1) do - delete :destroy, id: @plan_section - end - - assert_redirected_to plan_sections_path - end -=end -end diff --git a/test/functional/plans_controller_test.rb b/test/functional/plans_controller_test.rb index d2931bf..3811003 100644 --- a/test/functional/plans_controller_test.rb +++ b/test/functional/plans_controller_test.rb @@ -1,51 +1,276 @@ require 'test_helper' -class PlansControllerTest < ActionController::TestCase -=begin +class PlansControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + # TODO: Cleanup these routes! There are duplicates and ones no longer in use! + # + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # status_plan GET /plans/:id/status plans#status + # locked_plan GET /plans/:id/locked plans#locked + # answer_plan GET /plans/:id/answer plans#answer + # update_guidance_choices_plan PUT /plans/:id/update_guidance_choices plans#update_guidance_choices + # delete_recent_locks_plan POST /plans/:id/delete_recent_locks plans#delete_recent_locks + # lock_section_plan POST /plans/:id/lock_section plans#lock_section + # unlock_section_plan POST /plans/:id/unlock_section plans#unlock_section + # unlock_all_sections_plan POST /plans/:id/unlock_all_sections plans#unlock_all_sections + # export_plan GET /plans/:id/export plans#export + # warning_plan GET /plans/:id/warning plans#warning + # section_answers_plan GET /plans/:id/section_answers plans#section_answers + # share_plan GET /plans/:id/share plans#share + # GET /plans/:id/export plans#export + # invite_plan POST /plans/:id/invite plans#invite + # possible_templates_plans GET /plans/possible_templates plans#possible_templates + # possible_guidance_plans GET /plans/possible_guidance plans#possible_guidance + + # plans GET /plans plans#index + # POST /plans plans#create + # new_plan GET /plans/new plans#new + # edit_plan GET /plans/:id/edit plans#edit + # plan GET /plans/:id plans#show + # PATCH /plans/:id plans#update + # PUT /plans/:id plans#update + # DELETE /plans/:id plans#destroy + setup do - @plan = plans(:one) + @org = Org.first + scaffold_plan + @user = @plan.owner + + # This should NOT be unnecessary! Owner should have full access + role = Role.where(user: @user, plan: @plan).first + role.access = 15 + role.save! end - test "should get index" do - get :index + # GET /plans (plans_path) + # ---------------------------------------------------------- + test 'load the list of plans page' do + # Should redirect user to the root path if they are not logged in! + get plans_path + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get plans_path assert_response :success - assert_not_nil assigns(:plans) + assert assigns(:plans) end - - test "should get new" do - get :new + + # GET /plans/new (new_plan_path) + # ---------------------------------------------------------- + test 'load the new plan page' do + # Should redirect user to the root path if they are not logged in! + get new_plan_path + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get new_plan_path assert_response :success + assert assigns(:plan) + assert assigns(:orgs) + assert assigns(:funders) + assert assigns(:default_org) end - test "should create plan" do - assert_difference('Plan.count') do - post :create, plan: { locked: @plan.locked, project_id: @plan.project_id, version_id: @plan.version_id } - end - - assert_redirected_to plan_path(assigns(:plan)) - end - - test "should show plan" do - get :show, id: @plan + # POST /plans (plans_path) + # ---------------------------------------------------------- + test "create a new plan" do + params = {plan: {org_id: @template.org.id, template_id: @template.id, title: 'Testing Create'}} + # Should redirect user to the root path if they are not logged in! + post plans_path(format: :js), params + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post plans_path(format: :js), params + assert flash[:notice].include?(_('Plan was successfully created.')) assert_response :success - end + assert assigns(:plan) + assert_equal "Testing Create", Plan.last.title, "expected the record to have been created" + end - test "should get edit" do - get :edit, id: @plan + # GET /plan/:id (plan_path) + # ---------------------------------------------------------- + test 'show the plan page' do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(plan_path(@plan)) + + sign_in @user + get plan_path(@plan) assert_response :success + assert assigns(:plan) + assert_not assigns(:editing) + assert assigns(:selected_guidance_groups) end - test "should update plan" do - put :update, id: @plan, plan: { locked: @plan.locked, project_id: @plan.project_id, version_id: @plan.version_id } - assert_redirected_to plan_path(assigns(:plan)) + # PUT /plan/:id (plan_path) + # ---------------------------------------------------------- + test 'update the plan' do + params = {title: 'Testing UPDATE'} + # Should redirect user to the root path if they are not logged in! + put plan_path(@plan), {plan: params} + assert_unauthorized_redirect_to_root_path + + # User who is does not have access to the plan + sign_in User.first + put plan_path(@plan), {plan: params} + assert_equal _('You are not authorized to perform this action.'), flash[:notice] + assert_response :redirect + assert_redirected_to plans_url + + sign_in @user + + put plan_path(@plan), {plan: params} + assert_equal _('Plan was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to plan_url(@plan) + assert assigns(:plan) + assert_equal 'Testing UPDATE', @plan.reload.title, "expected the record to have been updated" + +# TODO: Reactivate this once the validations on the model are in place! + # Invalid object +# put plan_path(@plan), {plan: {title: nil}} +# assert flash[:notice].starts_with?(_('Could not update your')) +# assert_response :success +# assert assigns(:plan) end - - test "should destroy plan" do - assert_difference('Plan.count', -1) do - delete :destroy, id: @plan - end - + + # DELETE /plan/:id (plan_path) + # ---------------------------------------------------------- + test "delete the plan" do + id = @plan.id + # Should redirect user to the root path if they are not logged in! + delete plan_path(@plan) + assert_unauthorized_redirect_to_root_path + + # User who is does not have access to the plan + sign_in User.first + delete plan_path(@plan) + assert_equal _('You are not authorized to perform this action.'), flash[:notice] + assert_response :redirect + assert_redirected_to plans_url + + sign_in @user + delete plan_path(@plan) + assert_equal _('Plan was successfully deleted.'), flash[:notice] + assert_response :redirect + assert assigns(:plan) assert_redirected_to plans_path + assert_raise ActiveRecord::RecordNotFound do + Plan.find(id).nil? + end end -=end + + # PUT /plans/:id/update_guidance_choices (update_guidance_choices_plan_path) + # ---------------------------------------------------------- + test "update the selected guidance" do + params = {guidance_group_ids: [GuidanceGroup.first.id, GuidanceGroup.last.id]} + + # Make sure the guidance is attached to the template first so that its a valid selection! + q = @template.phases.first.sections.first.questions.first + q.themes << GuidanceGroup.first.guidances.first.themes.first + q.themes << GuidanceGroup.last.guidances.first.themes.first + q.save + + put update_guidance_choices_plan_path(@plan, format: :json), params + assert_unauthorized_redirect_to_root_path + + # User who does not have access to the plan + sign_in User.first + put update_guidance_choices_plan_path(@plan, format: :json), params + assert_equal _('You are not authorized to perform this action.'), flash[:notice] + assert_response :redirect + assert_redirected_to plans_url + + sign_in @user + put update_guidance_choices_plan_path(@plan, format: :json), params + assert_response :redirect + assert_redirected_to plan_path(@plan) + + @plan.reload + ggs = @plan.guidance_groups.ids + assert ggs.include?(GuidanceGroup.first.id), "expected the plan to have the first GuidanceGroup selected" + assert ggs.include?(GuidanceGroup.last.id), "expected the plan to have the last GuidanceGroup selected" + end + + # GET /plans/:id/share (share_plan_path) + # ---------------------------------------------------------- + test "get the share plan page" do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(share_plan_path(@plan)) + + sign_in @user + get share_plan_path(@plan) + assert_response :success + assert assigns(:plan) + end + + # GET /plans/:id/status(format: :json) (status_plan_path) + # ---------------------------------------------------------- + test "get the plan status" do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(status_plan_path(@plan, format: :json)) + + sign_in @user + get status_plan_path(@plan, format: :json) + assert_response :success + assert assigns(:plan) + end + + # GET /plans/:id/answer(format: :json) (answer_plan_path) + # ---------------------------------------------------------- + test "get the answer to the specified question for the plan" do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(answer_plan_path(@plan, format: :json)) + + sign_in @user + get answer_plan_path(@plan, format: :json) + assert_response :success + assert assigns(:plan) + end + + # GET /plans/:id/export (export_plan_path) + # ---------------------------------------------------------- + test "export the plan" do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(export_plan_path(@plan)) + + sign_in @user + get export_plan_path(@plan) + assert_response :success + assert assigns(:plan) + + # TODO: We need some better tests here to check the different formats! + end + + # GET /plans/:id/show_export (show_export_plan_path) + # ---------------------------------------------------------- + test "show the export the plan page" do + # Should redirect user to the root path if they are not logged in! + try_no_user_and_unauthorized(show_export_plan_path(@plan)) + + sign_in @user + get show_export_plan_path(@plan) + assert_response :success + assert assigns(:plan) + end + + private + def try_no_user_and_unauthorized(target) + # Should redirect user to the root path if they are not logged in! + get target + assert_unauthorized_redirect_to_root_path + + # User who is does not have access to the plan + sign_in User.first + get target + assert_equal _('You are not authorized to perform this action.'), flash[:notice] + assert_response :redirect + assert_redirected_to plans_url + end + end diff --git a/test/functional/project_groups_controller_test.rb b/test/functional/project_groups_controller_test.rb deleted file mode 100644 index 0e129f1..0000000 --- a/test/functional/project_groups_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class ProjectGroupsControllerTest < ActionController::TestCase -=begin - setup do - @project_group = project_groups(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:project_groups) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create project_group" do - assert_difference('ProjectGroup.count') do - post :create, project_group: { project_creator: @project_group.project_creator, project_editor: @project_group.project_editor, project_id: @project_group.project_id, user_id: @project_group.user_id } - end - - assert_redirected_to project_group_path(assigns(:project_group)) - end - - test "should show project_group" do - get :show, id: @project_group - assert_response :success - end - - test "should get edit" do - get :edit, id: @project_group - assert_response :success - end - - test "should update project_group" do - put :update, id: @project_group, project_group: { project_creator: @project_group.project_creator, project_editor: @project_group.project_editor, project_id: @project_group.project_id, user_id: @project_group.user_id } - assert_redirected_to project_group_path(assigns(:project_group)) - end - - test "should destroy project_group" do - assert_difference('ProjectGroup.count', -1) do - delete :destroy, id: @project_group - end - - assert_redirected_to project_groups_path - end -=end -end diff --git a/test/functional/project_partners_controller_test.rb b/test/functional/project_partners_controller_test.rb deleted file mode 100644 index c975fb2..0000000 --- a/test/functional/project_partners_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class ProjectPartnersControllerTest < ActionController::TestCase -=begin - setup do - @project_partner = project_partners(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:project_partners) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create project_partner" do - assert_difference('ProjectPartner.count') do - post :create, project_partner: { leader_org: @project_partner.leader_org, organisation_id: @project_partner.organisation_id, project_id: @project_partner.project_id } - end - - assert_redirected_to project_partner_path(assigns(:project_partner)) - end - - test "should show project_partner" do - get :show, id: @project_partner - assert_response :success - end - - test "should get edit" do - get :edit, id: @project_partner - assert_response :success - end - - test "should update project_partner" do - put :update, id: @project_partner, project_partner: { leader_org: @project_partner.leader_org, organisation_id: @project_partner.organisation_id, project_id: @project_partner.project_id } - assert_redirected_to project_partner_path(assigns(:project_partner)) - end - - test "should destroy project_partner" do - assert_difference('ProjectPartner.count', -1) do - delete :destroy, id: @project_partner - end - - assert_redirected_to project_partners_path - end -=end -end diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb deleted file mode 100644 index 4238699..0000000 --- a/test/functional/projects_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class ProjectsControllerTest < ActionController::TestCase -=begin - setup do - @project = projects(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:projects) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create project" do - assert_difference('Project.count') do - post :create, project: { dmptemplate_id: @project.dmptemplate_id, locked: @project.locked, note: @project.note, title: @project.title } - end - - assert_redirected_to project_path(assigns(:project)) - end - - test "should show project" do - get :show, id: @project - assert_response :success - end - - test "should get edit" do - get :edit, id: @project - assert_response :success - end - - test "should update project" do - put :update, id: @project, project: { dmptemplate_id: @project.dmptemplate_id, locked: @project.locked, note: @project.note, title: @project.title } - assert_redirected_to project_path(assigns(:project)) - end - - test "should destroy project" do - assert_difference('Project.count', -1) do - delete :destroy, id: @project - end - - assert_redirected_to projects_path - end -=end -end diff --git a/test/functional/question_themes_controller_test.rb b/test/functional/question_themes_controller_test.rb deleted file mode 100644 index e4d015f..0000000 --- a/test/functional/question_themes_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class QuestionThemesControllerTest < ActionController::TestCase -=begin - setup do - @question_theme = question_themes(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:question_themes) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create question_theme" do - assert_difference('QuestionTheme.count') do - post :create, question_theme: { question_id: @question_theme.question_id, theme_id: @question_theme.theme_id } - end - - assert_redirected_to question_theme_path(assigns(:question_theme)) - end - - test "should show question_theme" do - get :show, id: @question_theme - assert_response :success - end - - test "should get edit" do - get :edit, id: @question_theme - assert_response :success - end - - test "should update question_theme" do - put :update, id: @question_theme, question_theme: { question_id: @question_theme.question_id, theme_id: @question_theme.theme_id } - assert_redirected_to question_theme_path(assigns(:question_theme)) - end - - test "should destroy question_theme" do - assert_difference('QuestionTheme.count', -1) do - delete :destroy, id: @question_theme - end - - assert_redirected_to question_themes_path - end -=end -end diff --git a/test/functional/questions_controller_test.rb b/test/functional/questions_controller_test.rb index 6ecfde8..ce6414c 100644 --- a/test/functional/questions_controller_test.rb +++ b/test/functional/questions_controller_test.rb @@ -1,51 +1,149 @@ -require 'test_helper' - -class QuestionsControllerTest < ActionController::TestCase -=begin - setup do - @question = questions(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:questions) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create question" do - assert_difference('Question.count') do - post :create, question: { default_value: @question.default_value, dependency_id: @question.dependency_id, dependency_text: @question.dependency_text, guidance: @question.guidance, order: @question.order, parent_id: @question.parent_id, suggested_answer: @question.suggested_answer, text: @question.text, type: @question.type, section_id: @question.section_id } - end - - assert_redirected_to question_path(assigns(:question)) - end - - test "should show question" do - get :show, id: @question - assert_response :success - end - - test "should get edit" do - get :edit, id: @question - assert_response :success - end - - test "should update question" do - put :update, id: @question, question: { default_value: @question.default_value, dependency_id: @question.dependency_id, dependency_text: @question.dependency_text, guidance: @question.guidance, order: @question.order, parent_id: @question.parent_id, suggested_answer: @question.suggested_answer, text: @question.text, type: @question.type, section_id: @question.section_id } - assert_redirected_to question_path(assigns(:question)) - end - - test "should destroy question" do - assert_difference('Question.count', -1) do - delete :destroy, id: @question - end - - assert_redirected_to questions_path - end -=end -end +require 'test_helper' + +class QuestionsControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + @section = @template.phases.first.sections.first + + # Get the first Org Admin + scaffold_org_admin(@template.org) + + @question_format = QuestionFormat.where(option_based: false).first + end + +# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has +# these defined. They are defined multiple times though and we need to clean this up! In particular +# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates. +# We should just have: +# +# SHOULD BE: +# -------------------------------------------------- +# questions GET /templates/:template_id/phases/:phase_id/sections/:section_id/questions sections#index +# POST /templates/:template_id/phases/:phase_id/sections/:section_id/questions sections#create +# question GET /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#show +# PATCH /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#update +# PUT /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#update +# DELETE /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#destroy +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# admin_create_question POST /org/admin/templates/questions/:id/admin_create questions#admin_create +# admin_update_question PUT /org/admin/templates/questions/:id/admin_update questions#admin_update +# admin_destroy_question DELETE /org/admin/templates/questions/:id/admin_destroy questions#admin_destroy + + + # POST /org/admin/templates/questions/:id/admin_create (admin_create_question_path) + # ---------------------------------------------------------- + test "create a new question" do + params = {section_id: @section.id, text: 'Test Question', number: 9, question_format_id: @question_format.id} + + @section.phase.template.dirty = false + @section.phase.template.save! + + # Should redirect user to the root path if they are not logged in! + post admin_create_question_path(@section), {question: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + @new_question = Question.new + @new_question.number = @section.questions.count + 1 + example_answer = @new_question.annotations.build + example_answer.type = :example_answer + example_answer.save + post admin_create_question_path(@section), {question: params} + assert_response :redirect + assert assigns(:question) + assert_redirected_to admin_show_phase_url(id: @section.phase.id, edit: 'true', section_id: @section.id, question_id: Question.last.id) + assert_equal _('Information was successfully created.'), flash[:notice] + assert_equal 'Test Question', Question.last.text, "expected the record to have been created!" + + # Make sure that the template's dirty flag got set + assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid object + post admin_create_question_path(@section), {question: {section_id: @section.id, text: nil, question_format_id: @question_format.id}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:question) + assert assigns(:section) + assert assigns(:phase) + assert assigns(:edit) + assert assigns(:open) + assert assigns(:sections) + assert assigns(:section_id) + end + + # PUT /org/admin/templates/questions/:id/admin_update (admin_update_question_path) + # ---------------------------------------------------------- + test "update the question" do + params = {text: 'Question - UPDATE'} + + @section.phase.template.dirty = false + @section.phase.template.save! + + # Should redirect user to the root path if they are not logged in! + put admin_update_question_path(@section.questions.first), {question: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put admin_update_question_path(@section.questions.first), {question: params} + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_show_phase_url(id: @section.phase.id, edit: 'true', section_id: @section.id, question_id: @section.questions.first.id) + assert assigns(:phase) + assert assigns(:section) + assert assigns(:question) + assert_equal 'Question - UPDATE', @section.questions.first.text, "expected the record to have been updated" + + # Make sure that the template's dirty flag got set + assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid save + put admin_update_question_path(@section.questions.first), {question: {text: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:question) + assert assigns(:section) + assert assigns(:phase) + assert assigns(:edit) + assert assigns(:open) + assert assigns(:sections) + assert assigns(:section_id) + assert assigns(:question_id) + end + + # DELETE /org/admin/templates/questions/:id/admin_destroy (admin_destroy_question_path) + # ---------------------------------------------------------- + test "delete the question" do + id = @section.questions.first.id + + @section.phase.template.dirty = false + @section.phase.template.save! + + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_question_path(id: @section.id, question_id: id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_question_path(id: @section.id, question_id: id) + assert_response :redirect + assert assigns(:phase) + assert assigns(:section) + assert assigns(:question) + assert_redirected_to admin_show_phase_url(id: @section.phase.id, edit: 'true', section_id: @section.id) + assert_equal _('Information was successfully deleted.'), flash[:notice] + assert_raise ActiveRecord::RecordNotFound do + Question.find(id).nil? + end + + # Make sure that the template's dirty flag got set + assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true" + end + +end \ No newline at end of file diff --git a/test/functional/registrations_controller_test.rb b/test/functional/registrations_controller_test.rb new file mode 100644 index 0000000..ef0079b --- /dev/null +++ b/test/functional/registrations_controller_test.rb @@ -0,0 +1,154 @@ +require 'test_helper' + +class RegistrationsControllerTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + @user = User.first + end + + # ------------------------------------------------------------- + test "sign up form loads" do + get new_user_registration_path + + assert_response :success + assert_not '#new_user'.nil? + end + + # ------------------------------------------------------------- + test "user receives proper error messaging if they have not accepted terms" do + post user_registration_path, {user: {accept_terms: false}} + + assert_response :redirect + follow_redirect! + + assert_response :success + assert_equal _('You must accept the terms and conditions to register.'), flash[:alert] + end + + # ------------------------------------------------------------- + test "user receives proper error messaging if they have not provided a valid email and/or password" do + [ {}, + {email: 'foo.bar@test.org'}, # No Password or Confirmation + {password: 'test12345'}, # No Confirmation + {password_confirmation: 'test12345'}, # No Password + {password: 'test12345', password_confirmation: 'test12345'}, # No Email + {email: 'foo.bar@test.org', password: 'test', password_confirmation: 'test'}, # Password is too short + {email: 'foo.bar@test.org', password: 'test12345', password_confirmation: 'test123'}, # Passwords do not match + {email: 'foo.bar$test.org', password: 'test12345', password_confirmation: 'test12345'} # invalid email + ].each do |params| + post user_registration_path, {user: {accept_terms: 1}.merge(params)} + + assert_response :redirect + follow_redirect! + + assert_response :success + assert_equal _('Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long.'), flash[:alert] + end + end + + # ------------------------------------------------------------- + test "user is able to register and is auto-logged in and brought to profile page" do + form = {accept_terms: 1, + email: 'foo.bar@test.org', + password: 'Test12345', + password_confirmation: 'Test12345'} + + cntr = 1 + # Test the bare minimum requirements and then all options + [form, form.merge({email: "foo.bar#{cntr}@test.org", + organisation_id: Org.first.id})].each do |params| + post user_registration_path, {user: params} + + assert_response :redirect + assert_redirected_to root_url + + follow_redirect! + assert_response :redirect + assert_redirected_to plans_path + + cntr += 1 + end + end + + # ------------------------------------------------------------- + test "edit profile page loads when logged in" do + sign_in @user + + get edit_user_registration_path + + assert_response :success + assert_select '.main_page_content h1', _('Edit profile') + + end + + # ------------------------------------------------------------- + test "user is able to edit their profile" do + sign_in @user + + # Change name + put user_registration_path, {user: {email: @user.email, firstname: 'Testing', surname: 'UPDATE', org_id: Org.first.id}} + assert_equal _('Details successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to edit_user_registration_url + + # Change email but didn't provide password + put user_registration_path, {user: {email: 'something@else.org', firstname: @user.firstname, surname: @user.surname, org_id: Org.first.id}} + assert_response :success + assert_equal _('Please enter your password to change email address.'), flash[:notice] + +# TODO: These don't seem to be behaving as expected. There were several typos in the controller that have been fixed +# (succesfully_updated vs successfully_updated) +=begin + # Change email + put user_registration_path, {user: {email: 'something@else.org', current_password: 'password123', firstname: @user.firstname, surname: @user.surname}} + assert_equal _('Details successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to edit_user_registration_url + + # Change password but neglected to provide the password + put user_registration_path, {user: {password_confirmation: 'testing123', current_password: 'password123', firstname: @user.firstname, surname: @user.surname, email: @user.email}} + assert_response :success + assert flash[:notice].starts_with?(_('Unable to save your changes.')) + + # Change password but neglected to provide the password confirmation + put user_registration_path, {user: {password: 'testing123', current_password: 'password123', firstname: @user.firstname, surname: @user.surname, email: @user.email}} + assert_equal _('Please enter a password confirmation'), flash[:notice] + assert_response :success + + # Change password but the password and confirmation do not match + put user_registration_path, {user: {password: 'test123', password_confirmation: 'testing123', current_password: 'password123', firstname: @user.firstname, surname: @user.surname, email: @user.email}} + assert_equal _('Password and comfirmation must match'), flash[:notice] + assert_response :success + + # Change password + put user_registration_path, {user: {password: 'testing123', password_confirmation: 'testing123', current_password: 'password123', firstname: @user.firstname, surname: @user.surname, email: @user.email}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success +=end + + end + +# INVALID AUTH REROUTING CHECKS + # ------------------------------------------------------------- + test "sign up form does NOT load if already logged in" do + sign_in @user + get new_user_registration_path + + assert_authorized_redirect_to_plans_page + end + + # ------------------------------------------------------------- + test "edit profile page does NOT load if not logged in" do + get edit_user_registration_path + + assert_unauthorized_redirect_to_root_path + end + + # ------------------------------------------------------------- + test "can NOT edit profile if not logged in" do + post user_registration_path, {user: {firstname: 'Foo', surname: 'Bar'}} + + assert_unauthorized_redirect_to_root_path + end +end \ No newline at end of file diff --git a/test/functional/roles_controller_test.rb b/test/functional/roles_controller_test.rb new file mode 100644 index 0000000..7937867 --- /dev/null +++ b/test/functional/roles_controller_test.rb @@ -0,0 +1,130 @@ +require 'test_helper' + +class RolesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + scaffold_plan + scaffold_org_admin(@plan.template.org) + + # This should NOT be unnecessary! Owner should have full access + @plan.roles << Role.create(user: @user, plan: @plan, access: 15) + + end + +# TODO: Cleanup routes for this one. The controller currently only responds to create, update, destroy + +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# roles POST /roles roles#create +# role PATCH /roles/:id roles#update +# PUT /roles/:id roles#update +# DELETE /roles/:id roles#destroy + +# POST /roles (roles_path) + # ---------------------------------------------------------- + test "create a new role" do + + params = {plan_id: @plan.id, access_level: 4} + + # Should redirect user to the root path if they are not logged in! + post roles_path, {role: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Known user + @invitee = User.where.not(id: [@plan.owner.id, @user.id]).first + post roles_path, {user: @invitee.email, role: params} + assert_equal _('Plan shared with %{email}.') % {email: @invitee.email}, flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert_equal @invitee.id, Role.last.user_id, "expected the record to have been created!" + assert assigns(:role) + + # Share to already invited user + post roles_path, {user: @invitee.email, role: params} + assert_equal _('Plan is already shared with %{email}.') % {email: @invitee.email}, flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert_equal @invitee.id, Role.last.user_id, "expected no record to have been created!" + assert assigns(:role) + + # Unknown user + post roles_path, {user: 'unknown_user@org.org', role: params} + assert_equal _('Invitation to unknown_user@org.org issued successfully.'), flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert_equal User.find_by(email:'unknown_user@org.org').id, Role.last.user_id, "expected the record to have been created!" + assert assigns(:role) + + # Invite owner + @invitee = User.find_by(id: @plan.owner.id) + post roles_path, {user: @invitee.email, role: params} + assert_equal _('Cannot share plan with %{email} since that email matches with the owner of the plan.') % {email: @invitee.email}, flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert_not_equal @invitee.id, Role.last.user_id, "expected no record to have been created!" + assert assigns(:role) + + # Missing email + post roles_path, {role: {plan_id: @plan.id, access_level: 4}} + assert_equal _('Please enter an email address'), flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert assigns(:role) + end + + # PUT /role/:id (role_path) + # ---------------------------------------------------------- + test "update the role" do + @invitee = User.last + role = Role.create(user: @invitee, plan: @plan, access: 1) + params = {access_level: 2} + + # Should redirect user to the root path if they are not logged in! + put role_path(role), {role: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put role_path(role), {role: params} + assert_equal _('Sharing details successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert assigns(:role) + assert_equal 13, role.reload.access, "expected the record to have been updated" + +# TODO: Role should require a user, plan and an access level :/ + # Invalid save +# put role_path(role), {role: {user: nil}} +# assert flash[:notice].starts_with?(_('Unable to save your changes.')) +# assert_response :redirect +# assert_redirected_to share_plan_path(@plan) +# assert assigns(:role) + end + + # DELETE /role/:id (role_path) + # ---------------------------------------------------------- + test "delete the section" do + @invitee = User.last + role = Role.create(user: @invitee, plan: @plan, access: 1) + + # Should redirect user to the root path if they are not logged in! + delete role_path(role) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete role_path(role) + assert_equal _('Access removed'), flash[:notice] + assert_response :redirect + assert_redirected_to share_plan_path(@plan) + assert_raise ActiveRecord::RecordNotFound do + Role.find(role.id).nil? + end + end + +end diff --git a/test/functional/sections_controller_test.rb b/test/functional/sections_controller_test.rb index a3847e3..2856a89 100644 --- a/test/functional/sections_controller_test.rb +++ b/test/functional/sections_controller_test.rb @@ -1,51 +1,135 @@ -require 'test_helper' - -class SectionsControllerTest < ActionController::TestCase -=begin - setup do - @section = sections(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:sections) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create section" do - assert_difference('Section.count') do - post :create, section: { organisation_id: @section.organisation_id, description: @section.description, order: @section.order, title: @section.title, version_id: @section.version_id } - end - - assert_redirected_to section_path(assigns(:section)) - end - - test "should show section" do - get :show, id: @section - assert_response :success - end - - test "should get edit" do - get :edit, id: @section - assert_response :success - end - - test "should update section" do - put :update, id: @section, section: { organisation_id: @section.organisation_id, description: @section.description, order: @section.order, title: @section.title, version_id: @section.version_id } - assert_redirected_to section_path(assigns(:section)) - end - - test "should destroy section" do - assert_difference('Section.count', -1) do - delete :destroy, id: @section - end - - assert_redirected_to sections_path - end -=end -end +require 'test_helper' + +class SectionsControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + @phase = @template.phases.first + + # Get the first Org Admin + scaffold_org_admin(@template.org) + end + +# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has +# these defined. They are defined multiple times though and we need to clean this up! In particular +# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates. +# We should just have: +# +# SHOULD BE: +# -------------------------------------------------- +# sections GET /templates/:template_id/phases/:phase_id/sections sections#index +# POST /templates/:template_id/phases/:phase_id/sections sections#create +# section GET /templates/:template_id/phases/:phase_id/section/:id sections#show +# PATCH /templates/:template_id/phases/:phase_id/section/:id sections#update +# PUT /templates/:template_id/phases/:phase_id/section/:id sections#update +# DELETE /templates/:template_id/phases/:phase_id/section/:id sections#destroy +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# admin_create_section POST /org/admin/templates/sections/:id/admin_create sections#admin_create +# admin_update_section PUT /org/admin/templates/sections/:id/admin_update sections#admin_update +# admin_destroy_section DELETE /org/admin/templates/sections/:id/admin_destroy sections#admin_destroy + + + + # POST /org/admin/templates/sections/:id/admin_create (admin_create_section_path) + # ---------------------------------------------------------- + test "create a new section" do + params = {phase_id: @phase.id, title: 'Section Tester', number: 99} + + @phase.template.dirty = false + @phase.template.save! + + # Should redirect user to the root path if they are not logged in! + post admin_create_section_path(@phase), {section: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post admin_create_section_path(@phase), {section: params} + assert_response :redirect + assert_redirected_to admin_show_phase_url(id: @phase.id, edit: 'true', section_id: Section.last.id) + assert_equal _('Information was successfully created.'), flash[:notice] + assert_equal 'Section Tester', Section.last.title, "expected the record to have been created!" + + # Make sure that the template's dirty flag got set + assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid object + post admin_create_section_path(@phase), {section: {phase_id: @phase.id, title: nil}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:section) + assert assigns(:phase) + assert assigns(:edit) + assert assigns(:open) + assert assigns(:sections) + end + + # PUT /org/admin/templates/sections/:id/admin_update (admin_update_section_path) + # ---------------------------------------------------------- + test "update the section" do + params = {title: 'Phase - UPDATE'} + + @phase.template.dirty = false + @phase.template.save! + + # Should redirect user to the root path if they are not logged in! + put admin_update_section_path(@phase.sections.first), {section: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put admin_update_section_path(@phase.sections.first), {section: params} + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_show_phase_url(id: @phase.id, section_id: @phase.sections.first.id, edit: 'true') + assert_equal 'Phase - UPDATE', @phase.sections.first.title, "expected the record to have been updated" + + # Make sure that the template's dirty flag got set + assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true" + + # Invalid save + put admin_update_section_path(@phase.sections.first), {section: {title: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:section) + assert assigns(:phase) + assert assigns(:edit) + assert assigns(:open) + assert assigns(:sections) + assert assigns(:section_id) + end + + # DELETE /org/admin/templates/sections/:id/admin_destroy (admin_destroy_section_path) + # ---------------------------------------------------------- + test "delete the section" do + id = @phase.sections.first.id + + @phase.template.dirty = false + @phase.template.save! + + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_section_path(id: @phase.id, section_id: id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete admin_destroy_section_path(id: @phase.id, section_id: id) + assert_response :redirect + assert assigns(:section) + assert assigns(:phase) + assert_redirected_to admin_show_phase_url(id: @phase.id, edit: 'true' ) + assert_equal _('Information was successfully deleted.'), flash[:notice] + assert_raise ActiveRecord::RecordNotFound do + Section.find(id).nil? + end + + # Make sure that the template's dirty flag got set + assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true" + end + +end \ No newline at end of file diff --git a/test/functional/sessions_controller_test.rb b/test/functional/sessions_controller_test.rb new file mode 100644 index 0000000..a41e540 --- /dev/null +++ b/test/functional/sessions_controller_test.rb @@ -0,0 +1,63 @@ +require 'test_helper' + +class SessionsControllerTest < ActionDispatch::IntegrationTest + + include Warden::Test::Helpers + + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # new_user_session GET /users/sign_in sessions#new + # user_session POST /users/sign_in sessions#create + # destroy_user_session DELETE /users/sign_out sessions#destroy + + setup do + @user = User.first + end + + # POST /users/sign_in (user_session_path) + # ---------------------------------------------------------- + test "existing user's language setting is stored in the session and FastGettext" do + @user.language = Language.find_by(abbreviation: 'de') + @user.save! + post user_session_path, {user: {email: @user.email}} + assert_equal 'de', session[:locale], "expected the existing user's locale to have been set in the session" + assert_response :redirect + assert_redirected_to root_path + end + + # POST /users/sign_in (user_session_path) + # ---------------------------------------------------------- + test "unknown user's session[:locale] set to FastGettext.default_locale" do + post user_session_path, {user: {email: 'testing.session@example.org'}} + assert_equal nil, session[:locale], "expected the new user's locale to be empty" + assert_equal FastGettext.default_locale, FastGettext.locale, "expected the FastGettext to use the default locale" + assert_response :redirect + assert_redirected_to root_path + end + + # POST /users/sign_in (user_session_path) + # ---------------------------------------------------------- + test "existing user's Shibboleth id is captured" do + Warden.on_next_request do |proxy| + proxy.raw_session[:shibboleth_data] = {uid: 'abcdefg'} + end + post user_session_path, {user: {email: @user.email}, shibboleth_data: {uid: 'abcdefg'}} + assert_response :redirect + assert_redirected_to root_path + assert_equal 'abcdefg', @user.reload.shibboleth_id, "expected the existing user's shib id to have been set" + end + + # DELETE /users/sign_in (destroy_user_session_path) + # ---------------------------------------------------------- + test "delete the user session" do + delete destroy_user_session_path + assert_equal nil, session[:locale], "expected the locale to have been deleted from the session" + assert_response :redirect + if Rails.application.config.shibboleth_enabled + assert_redirected_to Rails.application.config.shibboleth_logout_url + root_url + else + assert_redirected_to root_path + end + end + +end diff --git a/test/functional/static_pages_controller_test.rb b/test/functional/static_pages_controller_test.rb new file mode 100644 index 0000000..a9d6df7 --- /dev/null +++ b/test/functional/static_pages_controller_test.rb @@ -0,0 +1,61 @@ +require 'test_helper' + +class StaticPagesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @public_plan = Plan.create!({title: 'Public Test Project', + template: Template.first, + visibility: :publicly_visible}) + end + + # ---------------------------------------------------------- + test "should only return plans with public visibility" do +# get public_plans_path(locale: I18n.locale) + +# assert_response :success +# assert_not_nil assigns(:plans) + +# all_public = true + +# assigns(:plans).each do |plan| +# all_public = false unless plan.publicly_visible? +# end + +# assert all_public, "expected all of the plans to have public visibility!" + end + + # ---------------------------------------------------------- + test "should export the publicly available plan" do + +# get public_export_path(locale: I18n.locale, id: @project) + + # Should be redirected to the plans controller's export function +# assert_redirected_to "#{export_project_plan_path(@project, @project.plans.first)}", "expected to be redirected to the exported plan" +# follow_redirect! + +# assert_redirected_to "blah" +# assert_response :success +# assert_equal Mime::PDF, response.content_type + end + + # ---------------------------------------------------------- + test "should NOT export a non-public plan to unauthorized users" do + # Set the is_public flag to false and try to access it when not logged in +# @public_plan.visibility = :privately_visible +# @public_plan.save! + +# get public_export_path(locale: I18n.locale, id: @public_plan) + +# assert_redirected_to "#{public_plans_path}", "expected to be redirected to the home page!" +# assert_equal _('This account does not have access to that plan.'), flash[:notice], "Expected an unauthorized message when trying to export a plan (via the public_export route) when the plan is not actually public" + +# sign_in User.first + +# get public_export_path(locale: I18n.locale, id: @public_plan) + +# assert_redirected_to "#{public_plans_path}", "expected to be redirected to the home page!" +# assert_equal _('This account does not have access to that plan.'), flash[:notice], "Expected an unauthorized message when trying to export a plan (via the public_export route) when the plan is not actually public" + end +end \ No newline at end of file diff --git a/test/functional/templates_controller_test.rb b/test/functional/templates_controller_test.rb new file mode 100644 index 0000000..0987259 --- /dev/null +++ b/test/functional/templates_controller_test.rb @@ -0,0 +1,329 @@ +require 'test_helper' + +class TemplatesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + + # Get the first Org Admin + scaffold_org_admin(@template.org) + end + +# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has +# these defined. We should remove the old routes to the 'admin_' prefixed methods as well. We should just +# have: +# +# SHOULD BE: +# -------------------------------------------------- +# templates GET /templates templates#index +# POST /templates templates#create +# template GET /template/[:id] templates#show +# PATCH /template/[:id] templates#update +# PUT /template/[:id] templates#update +# DELETE /template/[:id] templates#destroy +# edit_template GET /template/[:id]/edit templates#edit +# new_template GET /templates/new templates#new +# +# +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# admin_index_template GET /org/admin/templates/:id/admin_index(.:format) templates#admin_index +# admin_template_template GET /org/admin/templates/:id/admin_template(.:format) templates#admin_template +# admin_new_template GET /org/admin/templates/:id/admin_new(.:format) templates#admin_new +# admin_template_history_template GET /org/admin/templates/:id/admin_template_history(.:format) templates#admin_template_history +# admin_destroy_template DELETE /org/admin/templates/:id/admin_destroy(.:format) templates#admin_destroy +# admin_create_template POST /org/admin/templates/:id/admin_create(.:format) templates#admin_create +# admin_update_template PUT /org/admin/templates/:id/admin_update(.:format) templates#admin_update + + + # GET /org/admin/templates/:id/admin_index (admin_index_template_path) the :id here makes no sense! + # ---------------------------------------------------------- + test "get the list of admin templates" do + # Should redirect user to the root path if they are not logged in! + get admin_index_template_path(@user.org) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_index_template_path(@user.org) + assert_response :success + + assert assigns(:funder_templates) + assert assigns(:org_templates) + end + + # GET /org/admin/templates/:id/admin_template (admin_template_template_path) + # ---------------------------------------------------------- + test "get the admin template" do + # Should redirect user to the root path if they are not logged in! + get admin_template_template_path(@template) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_template_template_path(@template) + assert_response :success + + assert assigns(:template) + assert assigns(:hash) + assert assigns(:current) + end + +# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id + # GET /org/admin/templates/:id/admin_new (admin_new_template_path) + # ---------------------------------------------------------- + test "get the new admin template page" do + # Should redirect user to the root path if they are not logged in! + get admin_new_template_path(Template.last.id) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_new_template_path(Template.last.id) + assert_response :success + end + + # GET /org/admin/templates/:id/admin_template_history (admin_template_history_template_path) + # ---------------------------------------------------------- + test "get the admin template history page" do + # Should redirect user to the root path if they are not logged in! + get admin_template_history_template_path(@template) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_template_history_template_path(@template) + assert_response :success + + assert assigns(:template) + assert assigns(:templates) + assert assigns(:current) + end + + # DELETE /org/admin/templates/:id/admin_destroy (admin_destroy_template_path) + # ---------------------------------------------------------- + test "delete the admin template" do + id = @template.id + # Should redirect user to the root path if they are not logged in! + delete admin_destroy_template_path(@template) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + family = @template.dmptemplate_id + prior = Template.current(family) + + version_the_template + + current = Template.current(family) + + # Try to delete a historical version should fail + delete admin_destroy_template_path(prior) + assert_equal _('You cannot delete historical versions of this template.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_index_template_path + assert_not Template.find(prior.id).nil? + + # Try to delete the current version should work + delete admin_destroy_template_path(current) + assert_response :redirect + assert_redirected_to admin_index_template_path + assert_raise ActiveRecord::RecordNotFound do + Template.find(current.id).nil? + end + assert_equal prior, Template.current(family), "expected the old version to now be the current version" + end + +# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id + # POST /org/admin/templates/:id/admin_create (admin_create_template_path) + # ---------------------------------------------------------- + test "create a template" do + params = {title: 'Testing create route'} + + # Should redirect user to the root path if they are not logged in! + post admin_create_template_path(@user.org), {template: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + post admin_create_template_path(@user.org), {template: params} + assert_equal _('Information was successfully created.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_template_template_url(Template.last.id) + assert assigns(:template) + assert_equal 'Testing create route', Template.last.title, "expected the record to have been created!" + + # Invalid object + post admin_create_template_path(@user.org), {template: {title: nil, org_id: @user.org.id}} + assert flash[:notice].starts_with?(_('Could not create your')) + assert_response :success + assert assigns(:template) + assert assigns(:hash) + end + + # GET /org/admin/templates/:id/admin_update (admin_update_template_path) + # ---------------------------------------------------------- + test "update the admin template" do + params = {title: 'ABCD'} + + # Should redirect user to the root path if they are not logged in! + #get admin_template_template_path(@template) # Click on 'edit' + #@template = Template.current(@template.dmptemplate_id) # Edit working copy + put admin_update_template_path(@template), {template: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + family = @template.dmptemplate_id + prior = Template.current(family) + + version_the_template + + current = Template.current(family) + + # We shouldn't be able to edit a historical version + put admin_update_template_path(prior), {template: params} + assert_equal _('You can not edit a historical version of this template.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_template_template_url(prior) + assert assigns(:template) + + # Make sure we get the right response when editing an unpublished template + put admin_update_template_path(current), {template: params} + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :success + assert assigns(:template) + assert assigns(:hash) + assert_equal 'ABCD', current.reload.title, "expected the record to have been updated" + assert current.reload.dirty? + + # Make sure we get the right response when providing an invalid template + put admin_update_template_path(current), {template: {title: nil}} + assert flash[:notice].starts_with?(_('Could not update your')) + assert_response :success + assert assigns(:template) + assert assigns(:hash) + end + + # GET /org/admin/templates/:id/admin_customize (admin_customize_template_path) + # ---------------------------------------------------------- + test "customize a funder template" do + # Make sure we are redirected if we're not logged in + get admin_customize_template_path(@template) + assert_unauthorized_redirect_to_root_path + + funder_template = Template.create(org: Org.funders.first, title: 'Testing integration') + + # Sign in as the funder so that we cna publish the template + sign_in User.find_by(org: funder_template.org) + + put admin_publish_template_path(funder_template) + assert_response :redirect + assert_redirected_to admin_index_template_path(funder_template.org) + + # Sign in as the regular user so we can customize the funder template + sign_in @user + + template = Template.live(funder_template.dmptemplate_id) + + get admin_customize_template_path(template) + + customization = Template.where(customization_of: template.dmptemplate_id).last + + assert_response :redirect + assert_redirected_to admin_template_template_url(Template.last) + assert assigns(:template) + + assert_equal 0, customization.version + assert_not customization.published? + assert_not customization.dirty? + + # Make sure the funder templates data is not modifiable! + customization.phases.each do |p| + assert_not p.modifiable + p.sections.each do |s| + assert_not s.modifiable + s.questions.each do |q| + assert_not q.modifiable + end + end + end + end + + # GET /org/admin/templates/:id/admin_publish (admin_publish_template_path) + # ---------------------------------------------------------- + test "publish a template" do + # Should redirect user to the root path if they are not logged in! + put admin_publish_template_path(@template) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + family = @template.dmptemplate_id + prior = Template.current(family) + + version_the_template + + current = Template.current(family) + + # We shouldn't be able to edit a historical version + put admin_publish_template_path(prior) + assert_equal _('You can not publish a historical version of this template.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_template_template_url(prior) + assert assigns(:template) + + # Publish the current template + put admin_publish_template_path(current) + assert_equal _('Your template has been published and is now available to users.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_index_template_path(@user.org) + current = Template.current(family) + + # Update the description so that the template gets versioned + get admin_template_template_path(current) # Click on 'edit' + new_version = Template.current(family) # Edit working copy + put admin_update_template_path(new_version), {template: {description: "this is an update"}} + + # Make sure it versioned properly + new_version = Template.current(family) + assert_not_equal current.id = new_version.id, "expected it to create a new version" + assert_equal (current.version + 1), new_version.version, "expected the version to have incremented" + assert current.published?, "expected the old version to be published" + assert_not new_version.published?, "expected the new version to NOT be published" + assert_not current.dirty?, "expected the old dirty flag to be false" + assert new_version.dirty?, "expected the new dirty flag to be true" + assert_equal current.dmptemplate_id, new_version.dmptemplate_id, "expected the old and new versions to share the same dmptemplate_id" + end + + # GET /org/admin/templates/:id/admin_unpublish (admin_unpublish_template_path) + # ---------------------------------------------------------- + test "unpublish a template" do + # Should redirect user to the root path if they are not logged in! + put admin_unpublish_template_path(@template) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + family = @template.dmptemplate_id + prior = Template.current(family) + + version_the_template + + current = Template.current(family) + + # Publish it so we can unpublish + put admin_publish_template_path(current) + assert_not Template.live(family).nil? + + put admin_unpublish_template_path(current) + assert_equal _('Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_index_template_path(@user.org) + + # Make sure there are no published versions + assert Template.live(family).nil? + end +end diff --git a/test/functional/themes_controller_test.rb b/test/functional/themes_controller_test.rb deleted file mode 100644 index 3bae2d6..0000000 --- a/test/functional/themes_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class ThemesControllerTest < ActionController::TestCase -=begin - setup do - @theme = themes(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:themes) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create theme" do - assert_difference('Theme.count') do - post :create, theme: { description: @theme.description, title: @theme.title } - end - - assert_redirected_to theme_path(assigns(:theme)) - end - - test "should show theme" do - get :show, id: @theme - assert_response :success - end - - test "should get edit" do - get :edit, id: @theme - assert_response :success - end - - test "should update theme" do - put :update, id: @theme, theme: { description: @theme.description, title: @theme.title } - assert_redirected_to theme_path(assigns(:theme)) - end - - test "should destroy theme" do - assert_difference('Theme.count', -1) do - delete :destroy, id: @theme - end - - assert_redirected_to themes_path - end -=end -end diff --git a/test/functional/token_permission_types_controller_test.rb b/test/functional/token_permission_types_controller_test.rb new file mode 100644 index 0000000..f1cc342 --- /dev/null +++ b/test/functional/token_permission_types_controller_test.rb @@ -0,0 +1,30 @@ +require 'test_helper' + +class TokenPermissionTypesControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # token_permission_types GET /token_permission_types token_permission_types#index + + setup do + @user = User.first + end + + # GET /token_permission_types (token_permission_types_path) + # ---------------------------------------------------------- + test "retrieve the list of token permission types" do + # Should redirect user to the root path if they are not logged in! + get token_permission_types_path + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get token_permission_types_path + assert_response :success + assert assigns(:user) + assert assigns(:token_types) + end + +end \ No newline at end of file diff --git a/test/functional/user_identifiers_controller_test.rb b/test/functional/user_identifiers_controller_test.rb new file mode 100644 index 0000000..2488373 --- /dev/null +++ b/test/functional/user_identifiers_controller_test.rb @@ -0,0 +1,36 @@ +require 'test_helper' + +class UserIdentifiersControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + + setup do + @user = User.first + end + +# CURRENT RESULTS OF `rake routes` +# -------------------------------------------------- +# destroy_user_identifier DELETE /users/identifiers/:id user_identifiers#destroy + + + # DELETE /users/identifiers/:id (destroy_user_identifier_path) + # ---------------------------------------------------------- + test "delete the section" do + ui = UserIdentifier.create(user: @user, identifier_scheme: IdentifierScheme.first, identifier: 'TESTING') + + # Should redirect user to the root path if they are not logged in! + delete destroy_user_identifier_path(ui) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + delete destroy_user_identifier_path(ui) + assert flash[:notice].start_with?(_('Successfully unlinked your account from')), "expected the success message" + assert_response :redirect + assert_redirected_to edit_user_registration_path + assert_raise ActiveRecord::RecordNotFound do + UserIdentifier.find(ui.id).nil? + end + end + +end \ No newline at end of file diff --git a/test/functional/user_org_roles_controller_test.rb b/test/functional/user_org_roles_controller_test.rb deleted file mode 100644 index 8412e88..0000000 --- a/test/functional/user_org_roles_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class UserOrgRolesControllerTest < ActionController::TestCase -=begin - setup do - @user_role = user_org_roles(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:user_org_roles) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create user_org_role" do - assert_difference('UserOrgRole.count') do - post :create, user_org_role: { organisation_id: @user_org_role.organisation_id, user_id: @user_org_role.user_id, user_role_type_id: @user_org_role.user_role_type_id } - end - - assert_redirected_to user_org_role_path(assigns(:user_org_role)) - end - - test "should show user_org_role" do - get :show, id: @user_org_role - assert_response :success - end - - test "should get edit" do - get :edit, id: @user_org_role - assert_response :success - end - - test "should update user_org_role" do - put :update, id: @user_org_role, user_org_role: { organisation_id: @user_org_role.organisation_id, user_id: @user_org_role.user_id, user_role_type_id: @user_org_role.user_role_type_id } - assert_redirected_to user_org_role_path(assigns(:user_org_role)) - end - - test "should destroy user_org_role" do - assert_difference('UserOrgRole.count', -1) do - delete :destroy, id: @user_org_role - end - - assert_redirected_to user_org_roles_path - end -=end -end diff --git a/test/functional/user_role_types_controller_test.rb b/test/functional/user_role_types_controller_test.rb deleted file mode 100644 index 5686f79..0000000 --- a/test/functional/user_role_types_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class UserRoleTypesControllerTest < ActionController::TestCase -=begin - setup do - @user_role_type = user_role_types(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:user_role_types) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create user_role_type" do - assert_difference('UserRoleType.count') do - post :create, user_role_type: { description: @user_role_type.description, name: @user_role_type.name } - end - - assert_redirected_to user_role_type_path(assigns(:user_role_type)) - end - - test "should show user_role_type" do - get :show, id: @user_role_type - assert_response :success - end - - test "should get edit" do - get :edit, id: @user_role_type - assert_response :success - end - - test "should update user_role_type" do - put :update, id: @user_role_type, user_role_type: { description: @user_role_type.description, name: @user_role_type.name } - assert_redirected_to user_role_type_path(assigns(:user_role_type)) - end - - test "should destroy user_role_type" do - assert_difference('UserRoleType.count', -1) do - delete :destroy, id: @user_role_type - end - - assert_redirected_to user_role_types_path - end -=end -end diff --git a/test/functional/user_statuses_controller_test.rb b/test/functional/user_statuses_controller_test.rb deleted file mode 100644 index 7487419..0000000 --- a/test/functional/user_statuses_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class UserStatusesControllerTest < ActionController::TestCase -=begin - setup do - @user_status = user_statuses(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:user_statuses) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create user_status" do - assert_difference('UserStatus.count') do - post :create, user_status: { description: @user_status.description, name: @user_status.name } - end - - assert_redirected_to user_status_path(assigns(:user_status)) - end - - test "should show user_status" do - get :show, id: @user_status - assert_response :success - end - - test "should get edit" do - get :edit, id: @user_status - assert_response :success - end - - test "should update user_status" do - put :update, id: @user_status, user_status: { description: @user_status.description, name: @user_status.name } - assert_redirected_to user_status_path(assigns(:user_status)) - end - - test "should destroy user_status" do - assert_difference('UserStatus.count', -1) do - delete :destroy, id: @user_status - end - - assert_redirected_to user_statuses_path - end -=end -end diff --git a/test/functional/user_types_controller_test.rb b/test/functional/user_types_controller_test.rb deleted file mode 100644 index 267ef27..0000000 --- a/test/functional/user_types_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class UserTypesControllerTest < ActionController::TestCase -=begin - setup do - @user_type = user_types(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:user_types) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create user_type" do - assert_difference('UserType.count') do - post :create, user_type: { description: @user_type.description, name: @user_type.name } - end - - assert_redirected_to user_type_path(assigns(:user_type)) - end - - test "should show user_type" do - get :show, id: @user_type - assert_response :success - end - - test "should get edit" do - get :edit, id: @user_type - assert_response :success - end - - test "should update user_type" do - put :update, id: @user_type, user_type: { description: @user_type.description, name: @user_type.name } - assert_redirected_to user_type_path(assigns(:user_type)) - end - - test "should destroy user_type" do - assert_difference('UserType.count', -1) do - delete :destroy, id: @user_type - end - - assert_redirected_to user_types_path - end -=end -end diff --git a/test/functional/users/omniauth_callbacks_controller_test.rb b/test/functional/users/omniauth_callbacks_controller_test.rb new file mode 100644 index 0000000..d4f7e58 --- /dev/null +++ b/test/functional/users/omniauth_callbacks_controller_test.rb @@ -0,0 +1,82 @@ +class OmniauthCallbacksControllerTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + @schemes = IdentifierScheme.all + @user = User.first + + @callback_uris = {} + + # Stub out omniauth provider responses + OmniAuth.config.test_mode = true + + @schemes.each do |scheme| + @callback_uris[scheme.name] = Rails.application.routes.url_helpers.send( + "user_#{scheme.name.downcase}_omniauth_callback_path") + + OmniAuth.config.mock_auth[:"#{scheme.name.downcase}"] = OmniAuth::AuthHash.new({ + :provider => "#{scheme.name.downcase}", + :uid => 'foo:bar' + }) + end + + end + + # ------------------------------------------------------------- + test "User is not signed in and valid OAuth2 response does not match a User record in DB: should redirect to registration page" do + @schemes.each do |scheme| + post @callback_uris[scheme.name], locale: FastGettext.locale + + assert_equal I18n.t('identifier_schemes.new_login_success'), flash[:notice], "Expected a success message when simulating a valid callback from #{scheme.name}" + + assert @response.redirect_url.include?(new_user_registration_url), "Expected a redirect to the registration page when the user is not logged in and we received a valid callback from #{scheme.name}" + + # make sure that the omniauth identifier is a hidden field on the registration page + assert_not "#user_identifiers[#{scheme.name}]".nil? + end + end + + # ------------------------------------------------------------- + test "User is not signed in and valid OAuth2 login matches a User record in the DB: should auto-signin and redirect to root page" do + + @schemes.each do |scheme| + @user.firstname = 'Tester' + @user.surname = 'MacTesting' + @user.user_identifiers << UserIdentifier.new(identifier_scheme: scheme, + identifier: "foo:bar") + @user.save! + + post @callback_uris[scheme.name] + + ### Until ORCID login becomes supported. + if scheme.name == 'shibboleth' + assert [I18n.t('devise.omniauth_callbacks.user.success').gsub('%{kind}', scheme.description).downcase, + I18n.t('devise.omniauth_callbacks.success').gsub('%{kind}', scheme.description).downcase].include?(flash[:notice].downcase), "Expected a success message when simulating a valid callback from #{scheme.name}" + assert @response.redirect_url.include?(root_url), "Expected a redirect to the root page, #{root_url}, when omniauth returns with a valid identifier!" + else + assert_equal I18n.t('identifier_schemes.new_login_success'), flash[:notice], "Expected a success message when simulating a valid callback from #{scheme.name}" + assert @response.redirect_url.include?(new_user_registration_url), "Expected a redirect to the registration page when the user is not logged in and we received a valid callback from #{scheme.name}" + assert_not "#user_identifiers[#{scheme.name}]".nil? + end + end + end + + # ------------------------------------------------------------- + test "User is signed in and valid OAuth2 login does not match the current user's record in the DB: should attach the identifier to the user and redirect to the edit profile page" do + + @schemes.each do |scheme| + sign_in @user + + post @callback_uris[scheme.name] + + assert_equal _("Your account has been successfully linked to %{scheme}.") % { scheme: scheme.description }, flash[:notice], "Expected a success message when simulating a valid callback from #{scheme.name}" + + assert_redirected_to "#{edit_user_registration_path}", "Expected a redirect to the edit profile page, #{edit_user_registration_path}, when omniauth returns with a valid identifier for a user that is already signed in!" + + # reload the user record and make sure the omniauth value was attached to their record + usr = User.find(@user.id) + assert_equal usr.user_identifiers.find_by(identifier_scheme: scheme).identifier, 'foo:bar' + end + end + +end diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 42d26cf..8f4eddc 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -1,51 +1,74 @@ require 'test_helper' -class UsersControllerTest < ActionController::TestCase -=begin +class UsersControllerTest < ActionDispatch::IntegrationTest + + include Devise::Test::IntegrationHelpers + setup do - @user = users(:one) + scaffold_org_admin(Org.last) end + + # TODO: Reassess these routes. Devise handles the standard profile pages so defining a more RESTful setup + # wouldn't conflict with the update/create of the main user object. They should probably be something like: + # + # users GET /org/:org_id/users users#index + # user GET /user/:id users#show + # user PUT /user/:id users#update + + # CURRENT RESULTS OF `rake routes` + # -------------------------------------------------- + # admin_index_users GET /org/admin/users/admin_index users#admin_index + # admin_grant_permissions_user GET /org/admin/users/:id/admin_grant_permissions users#admin_grant_permissions + # admin_update_permissions_user PUT /org/admin/users/:id/admin_update_permissions users#admin_update_permissions - test "should get index" do - get :index + + # GET /org/admin/users/admin_index (admin_index_users_path) + # ---------------------------------------------------------- + test "get the list of users" do + # Should redirect user to the root path if they are not logged in! + get admin_index_users_path + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_index_users_path assert_response :success - assert_not_nil assigns(:users) + assert assigns(:users) end - - test "should get new" do - get :new + + # GET /org/admin/users/:id/admin_grant_permissions (admin_grant_permissions_user_path) + # ---------------------------------------------------------- + test "grant the user's permissions" do + # Should redirect user to the root path if they are not logged in! + get admin_grant_permissions_user_path(@user.org.users.first) + assert_unauthorized_redirect_to_root_path + + sign_in @user + + get admin_grant_permissions_user_path(@user.org.users.first) assert_response :success + assert assigns(:user) + assert assigns(:perms) end - test "should create user" do - assert_difference('User.count') do - post :create, user: { email: @user.email, firstname: @user.firstname, last_login: @user.last_login, login_count: @user.login_count, orcid_id: @user.orcid_id, password: @user.password, shibboleth_id: @user.shibboleth_id, user_status_id: @user.user_status_id, surname: @user.surname, user_type_id: @user.user_type_id } + # PUT /org/admin/users/:id/admin_update_permissions (admin_update_permissions_user_path) + # ---------------------------------------------------------- + test "update the user's permissions" do + params = {perm_ids: [Perm.last.id, Perm.first.id]} + + # Should redirect user to the root path if they are not logged in! + put admin_update_permissions_user_path(@user.org.users.last), {user: params} + assert_unauthorized_redirect_to_root_path + + sign_in @user + + # Valid save + put admin_update_permissions_user_path(@user.org.users.last), {user: params} + assert_equal _('Information was successfully updated.'), flash[:notice] + assert_response :redirect + assert_redirected_to admin_index_users_url + @user.org.users.last.perms.each do |perm| + assert params[:perm_ids].include?(perm.id), "did not expect to find the #{perm.name} attached to the user" end - - assert_redirected_to user_path(assigns(:user)) end - - test "should show user" do - get :show, id: @user - assert_response :success - end - - test "should get edit" do - get :edit, id: @user - assert_response :success - end - - test "should update user" do - put :update, id: @user, user: { email: @user.email, firstname: @user.firstname, last_login: @user.last_login, login_count: @user.login_count, orcid_id: @user.orcid_id, password: @user.password, shibboleth_id: @user.shibboleth_id, user_status_id: @user.user_status_id, surname: @user.surname, user_type_id: @user.user_type_id } - assert_redirected_to user_path(assigns(:user)) - end - - test "should destroy user" do - assert_difference('User.count', -1) do - delete :destroy, id: @user - end - - assert_redirected_to users_path - end -=end end diff --git a/test/functional/versions_controller_test.rb b/test/functional/versions_controller_test.rb deleted file mode 100644 index a3c4be7..0000000 --- a/test/functional/versions_controller_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'test_helper' - -class VersionsControllerTest < ActionController::TestCase -=begin - setup do - @version = versions(:one) - end - - test "should get index" do - get :index - assert_response :success - assert_not_nil assigns(:versions) - end - - test "should get new" do - get :new - assert_response :success - end - - test "should create version" do - assert_difference('Version.count') do - post :create, version: { description: @version.description, order: @version.order, published: @version.published, title: @version.title } - end - - assert_redirected_to version_path(assigns(:version)) - end - - test "should show version" do - get :show, id: @version - assert_response :success - end - - test "should get edit" do - get :edit, id: @version - assert_response :success - end - - test "should update version" do - put :update, id: @version, version: { description: @version.description, order: @version.order, published: @version.published, title: @version.title } - assert_redirected_to version_path(assigns(:version)) - end - - test "should destroy version" do - assert_difference('Version.count', -1) do - delete :destroy, id: @version - end - - assert_redirected_to versions_path - end -=end -end diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb new file mode 100644 index 0000000..11aec2a --- /dev/null +++ b/test/helpers/application_helper_test.rb @@ -0,0 +1,61 @@ +require 'test_helper' + +class ApplicationHelperTest < ActionView::TestCase + + def setup + # initialize the ActionView Output so that we have access to its functions (e.g. content_for) + @view_flow = ActionView::OutputFlow.new + + content_for(:head) do + "Testing".html_safe + end + end + + # ----------------------------------------------------------------------- + test "resource_name should return :user" do + assert_equal :user, resource_name + end + + # ----------------------------------------------------------------------- + test "resource should return contents of instance variable @resource OR a new User" do + # If @resource is not set then we should receive a new User + assert resource.is_a?(User), "Expected resource() to return a new User" + assert_equal nil, resource.id, "Expected resource() to return a User with an Id" + + # If @resource is set then we should receive that object + @resource = Org.first + assert resource.is_a?(Org), "Expected resource() to return @resource" + assert_equal @resource.id, resource.id, "Expected resource() to return the first Organisation" + end + + # ----------------------------------------------------------------------- + test "devise_mapping should return the mappings registered for Devise" do + # If @devise_mappings is not set we should get the mappings for :user + assert_equal Devise.mappings[:user], devise_mapping, "Expected devise_mapping() to return the correct default" + + # If @devise_mapping is set the we should receive it + @devise_mapping = {foo: 'bar'} + assert_equal @devise_mapping, devise_mapping, "Expected devise_mapping() to return @devise_mapping" + end + + # ----------------------------------------------------------------------- + test "javascript should add JS script tags to the HTML head content for each of the files provided" do + current = content_for(:head) + + javascript('abc.js') + assert content_for(:head).include?("#{javascript_include_tag('abc.js')}"), "Expected the abc.js script to be added to the HTML head content but got: #{content_for(:head)}" + + javascript('zyx.js', 'wvu.js') + assert content_for(:head).include?("#{javascript_include_tag('wvu.js')}"), "Expected the wvu.js script to be added to the HTML head content but got: #{content_for(:head)}" + assert content_for(:head).include?("#{javascript_include_tag('zyx.js')}"), "Expected the zyx.js script to be added to the HTML head content but got: #{content_for(:head)}" + end + + # ----------------------------------------------------------------------- + test "hash_to_js_json_variable should return valid JSON markup for the specified Hash object" do + actual = hash_to_js_json_variable('hasher', {foo: 'bar', abc: '123'}) + + assert actual.include?('script'), "Expected the result to be contained within a script tag but got: #{actual}" + assert actual.include?('var hasher = '), "Expected the hash to appear as a variable but got: #{actual}" + assert actual.include?('{"foo":"bar","abc":"123"}'), "Expected the hash contents to appear but got: #{actual}" + end +end \ No newline at end of file diff --git a/test/helpers/plans_helper_test.rb b/test/helpers/plans_helper_test.rb new file mode 100644 index 0000000..f83d738 --- /dev/null +++ b/test/helpers/plans_helper_test.rb @@ -0,0 +1,91 @@ +require 'test_helper' + +class PlansHelperTest < ActionView::TestCase + + include Devise::Test::IntegrationHelpers + + UNKNOWN = I18n.t("helpers.project.columns.unknown") + + def setup + scaffold_plan + + @user = User.last + sign_in @user + end + +=begin + # ----------------------------------------------------------------------- + test "plan_list_column_heading should return the localized text for the column heading" do + cols = I18n.t("helpers.project.columns") + + cols.each do |k,v| + assert plan_list_column_heading(k.to_s).include?(">#{I18n.t("helpers.project.columns.#{k}")}<"), "expected #{k} to return a column heading labeled #{v}" + end + + assert plan_list_column_heading(["test1", 18, 'test3']).include?("Test1"), "expected the 1st item in the array if its a String" + assert plan_list_column_heading([18, 'test3']).include?(UNKNOWN), "expected 'Unknown' if the 1st item in the array if is NOT a String" + + assert plan_list_column_heading(18).include?(UNKNOWN), "expected 'Unknown' if the value passed is not a String or an Array" + end + + # ----------------------------------------------------------------------- + test "plan_list_column_body should return the localized text for the column heading" do + cols = I18n.t("helpers.project.columns") + + assert plan_list_column_body(["non_link_name", "owner"], @plan).include?(@plan.title), "expected the 1st column to be used if passing in an Array" + + cols.each do |k,v| + val = plan_list_column_body(k.to_s, @plan) + + if Plan.respond_to?(k) + assert plan_list_column_body(k.to_s, @plan).include?(">#{@plan.send(k)}<"), "expected #{k} to return a column containing the Plan's value for that column. Instead got: #{val}" + + else + if k == :owner + assert val.include?(">#{@plan.users.first.name}<") || val.include?(t("helpers.me")), "expected :owner to return a column containing the Plan's value for that column or #{I18n.t("helpers.me")}. Instead got: #{val}" + + elsif k == :shared? + assert val.include?(">Yes<") || val.include?(">No<"), "expected :shared? to return a column containing Yes/No. Instead got: #{val}" + else + + end + end + + end + + # Check different return options for the plan's owner + plan = Plan.create(template: @template, title: 'No owner test') + user = User.create(email: 'tester@example.com', firstname: 'Test', surname: 'Er', password: '123password') + + assert plan_list_column_body('owner', plan).include?(UNKNOWN), "expected Unknown if the column is 'owner' but the plan has no owner" + + plan.assign_creator(user.id) + plan.save! + plan.reload + + assert plan_list_column_body('owner', plan).include?(user.name), "expected the user's name if the column is 'owner' and the plan owner is not the current user" + end + + # TODO: 'custom_template' is part of the case logic in this method but it is unreachable + # because both the plan and template settings objects use "Settings::Template". We + # should remove it from logic + # ----------------------------------------------------------------------- + test "plan_settings_indicator should return the correct export formatting settings" do + assert plan_settings_indicator(@plan).include?(">#{I18n.t("helpers.settings.plans.default_formatting")}<"), "expected the default plan to use default export settings" + + @plan.settings(:export).formatting = {margin: {top: 5, bottom: 5, left: 5, right: 5}, + font_face: Settings::Template::VALID_FONT_FACES.last, + font_size: 12} + @plan.save! + + assert plan_settings_indicator(@plan).include?(">#{I18n.t("helpers.settings.plans.template_formatting")}<"), "expected the default plan to use default export settings" + + @plan.template.settings(:export).formatting = {margin: {top: 10, bottom: 10, left: 10, right: 10}, + font_face: Settings::Template::VALID_FONT_FACES.first, + font_size: 11} + @plan.save! + + assert plan_settings_indicator(@plan).include?(">#{I18n.t("helpers.settings.plans.template_formatting")}<"), "expected the default plan to use default export settings" + end +=end +end diff --git a/test/integration/.gitkeep b/test/integration/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/test/integration/.gitkeep +++ /dev/null diff --git a/test/integration/answer_locking_test.rb b/test/integration/answer_locking_test.rb new file mode 100644 index 0000000..0c0bb0f --- /dev/null +++ b/test/integration/answer_locking_test.rb @@ -0,0 +1,107 @@ +require 'test_helper' + +class AnswerLockingTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + scaffold_plan + @question = Question.create(text: 'Test question', section: @plan.template.phases.first.sections.first, + question_format: QuestionFormat.where(option_based: false).first, number: 99) + + @collaborator = (User.first == @plan.owner ? User.last : User.first) + + # Make the 2nd user an editor of the plan + Role.create!(user_id: @collaborator.id, plan_id: @plan.id, access: 4) + @plan.reload + end + + # ---------------------------------------------------------- + test 'user receives a lock notification if the answer was CREATED while they were working' do + userA = Answer.new(user: @plan.owner, plan: @plan, question: @question, + text: "Initial answer - by UserA") + + userB = Answer.new(user: @collaborator, plan: @plan, question: @question, + text: "Version conflict at onset - by UserB") + + # Signin as UserA and insert the new answer + sign_in @plan.owner + put answer_path(FastGettext.locale, userA, format: "js"), obj_to_params(userA.attributes) + assert_response :success + assert_equal "text/javascript", @response.content_type + updated = Answer.find_by(plan: @plan, question: @question) + assert_equal "Initial answer - by UserA", updated.text + assert_equal @plan.owner.id, updated.user_id + + # Make sure the answers/locking partial is NOT displayed + assert_not @response.body.include?(_('The following answer cannot be saved')), "expected there to be no lock error messaging" + assert @response.body.include?(_('Answered')) + assert @response.body.include?("#{_(' by')} #{@plan.owner.name}"), "expected the messaging to say the plan was updated by the plan owner" + + # Signin as UserB and try to insert the new answer but fail + sign_in @collaborator + put answer_path(FastGettext.locale, userB, format: "js"), obj_to_params(userB.attributes) + assert_response :success + assert_equal "text/javascript", @response.content_type + updated = Answer.find_by(plan: @plan, question: @question) + assert_equal "Initial answer - by UserA", updated.text + assert_equal @plan.owner.id, updated.user_id + + # Make sure the answer-notice IS displayed + assert @response.body.include?(_('The following answer cannot be saved')), "expected there to be lock error messaging" + assert @response.body.include?(_('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: @plan.owner.name}), "expected the messaging to STILL say the plan was updated by the plan owner" + assert @response.body.include?(_('Answered')), "expected the messaging to include the status" + end + + # ---------------------------------------------------------- + test 'user receives a lock notification if the answer was UPDATED while they were working' do + userA = Answer.create!(user: @plan.owner, plan: @plan, question: @question, + text: "Initial answer - by UserA").attributes + userB = userA.clone + + # Signin as UserA and insert the new answer + sign_in @plan.owner + userA['text'] += " - Updated by userA" + + put answer_path(FastGettext.locale, userA['id'], format: "js"), obj_to_params(userA) + assert_response :success + assert_equal "text/javascript", @response.content_type + updated = Answer.find_by(plan: @plan, question: @question) + assert_equal "Initial answer - by UserA - Updated by userA", updated.text + assert_equal @plan.owner.id, updated.user_id + + # Make sure the answers/locking partial is NOT displayed + assert_not @response.body.include?(_('The following answer cannot be saved')), "expected there to be no lock error messaging" + assert @response.body.include?(_('Answered')) + assert @response.body.include?("#{_(' by')} #{@plan.owner.name}"), "expected the messaging to say the plan was updated by the plan owner" + + # Signin as UserB and try to insert the new answer but fail + sign_in @collaborator + userB['text'] += " - Updated by userB" + + put answer_path(FastGettext.locale, userB['id'], format: "js"), obj_to_params(userB) + assert_response :success + assert_equal "text/javascript", @response.content_type + updated = Answer.find_by(plan: @plan, question: @question) + assert_equal "Initial answer - by UserA - Updated by userA", updated.text + assert_equal @plan.owner.id, updated.user_id + + # Make sure the answer-notice IS displayed + assert @response.body.include?(_('The following answer cannot be saved')), "expected there to be lock error messaging" + assert @response.body.include?(_('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: @plan.owner.name}), "expected the messaging to STILL say the plan was updated by the plan owner" + assert @response.body.include?(_('Answered')), "expected the messaging to include the status" + end + +# ---------------------------------------------------------- + private + def obj_to_params(attributes) + { + answer: {id: attributes['id'], + user_id: attributes['user_id'], + plan_id: attributes['plan_id'], + question_id: attributes['question_id'], + text: attributes['text'], + lock_version: attributes['lock_version']} + } + end +end diff --git a/test/integration/authentication_test.rb b/test/integration/authentication_test.rb new file mode 100644 index 0000000..c9d4c26 --- /dev/null +++ b/test/integration/authentication_test.rb @@ -0,0 +1,84 @@ +require 'test_helper' + +class AuthenticationFlowTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + @user = User.first + end + + # ---------------------------------------------------------- + test 'can sign in with valid email and password' do + sign_in @user + + get root_path + + assert_authorized_redirect_to_plans_page + end + + # ---------------------------------------------------------- + test 'can sign in with shibboleth' do + + end + + # ---------------------------------------------------------- + test 'can sign out' do + get root_path + assert_response :success + + sign_in @user + + delete destroy_user_session_path + + assert_response :redirect + if Rails.application.config.shibboleth_enabled + assert_redirected_to Rails.application.config.shibboleth_logout_url + root_url + else + assert_redirected_to root_path + end + get root_path + + # Make sure that the user is sent to the page that lists their plans + assert_select '.welcome-message h2', _('Welcome.') + end + + # ---------------------------------------------------------- + test 'can NOT sign in with an invalid email and/or password' do + get root_path + assert_response :success + + users = [{email: @user.email, password: 'bAd_pas$word1', remember_me: true}, + {email: 'unknown@institution.org', password: 'password123', remember_me: true}] + + users.each do |params| + post user_session_path, user: params + + assert_response :redirect + follow_redirect! + + # Make sure that the user is sent to the page that lists their plans + assert_response :success + assert_select '.welcome-message h2', _('Welcome.') + end + end + + + private + # ---------------------------------------------------------- +=begin + def sign_in + post user_session_path, user: { + email: @user.email, + password: 'password123', + remember_me: false + } + + # The Devise auth gem will end up performing 2 redirects while generating the user's + # session and sending them to the main landing page + 2.times do + assert_response :redirect + follow_redirect! + end + end +=end +end diff --git a/test/integration/template_selection_test.rb b/test/integration/template_selection_test.rb new file mode 100644 index 0000000..2567954 --- /dev/null +++ b/test/integration/template_selection_test.rb @@ -0,0 +1,140 @@ +require 'test_helper' + +class TemplateSelectionTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + scaffold_template + @template.is_default = true + @template.published = true + @template.save! + + @researcher = User.last + + scaffold_org_admin(@template.org) + + @funder = Org.find_by(org_type: 2) + @funder_template = Template.create(title: 'Funder template', org: @funder, migrated: false) + # Template can't be published on creation so do it afterward + @funder_template.published = true + @funder_template.save + + @org = @researcher.org + @org_template = Template.create(title: 'Org template', org: @org, migrated: false) + # Template can't be published on creation so do it afterward + @org_template.published = true + @org_template.save + end + + # ---------------------------------------------------------- + test 'plan gets publish versions of templates' do + original_id = @template.id + template = version_template(@template) + + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @template.org.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{original_id}\");") + assert_equal original_id, Template.live(@template.dmptemplate_id).id + + # Version the template again + original_id = template.id + template = version_template(template) + + # Make sure the published version is used + post plans_path(format: :js), {plan: {org_id: @template.org.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{original_id}\");") + assert_equal original_id, Template.live(@template.dmptemplate_id).id + + # Update the template and make sure the published version stayed the same + sign_in @user + put admin_update_template_path(template), {template: {title: "Blah blah blah"}} + + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @template.org.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{original_id}\");") + assert_equal original_id, Template.live(@template.dmptemplate_id).id + end + + # ---------------------------------------------------------- + test 'plan gets generic template when no funder or org' do + @template.is_default = true + @template.save! + + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: nil}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{@template.id}\");"), @response.body + end + + # ---------------------------------------------------------- + test 'plan gets org template when no funder' do + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @org.id, funder_id: nil}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{@org_template.id}\");"), @response.body + end + + # ---------------------------------------------------------- + test 'plan gets funder template when no org' do + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: nil, funder_id: @funder.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{@funder_template.id}\");"), @response.body + end + + # ---------------------------------------------------------- + test 'plan gets funder template when org has no customization' do + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @org.id, funder_id: @funder.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{@funder_template.id}\");"), @response.body + end + + # ---------------------------------------------------------- + test 'plan gets customized version of funder template' do + customization = Template.create(title: 'Customization', org: @org) + # Template can't be published on creation so do it afterward + customization.published = true + customization.customization_of = @funder_template.dmptemplate_id + customization.save + + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @org.id, funder_id: @funder.id}} + assert_response :success + assert @response.body.include?("$(\"#plan_template_id\").val(\"#{customization.id}\");"), @response.body + end + + # ---------------------------------------------------------- + test 'list of templates is returned when the funder has multiples' do + funder_template2 = Template.create(title: 'Funder template 2', org: @funder) + # Template can't be published on creation so do it afterward + funder_template2.published = true + funder_template2.save + + sign_in @researcher + + post plans_path(format: :js), {plan: {org_id: @org.id, funder_id: @funder.id}} + assert_response :success + assert_select "option", 3, "expected a dropdown with 2 templates and a 'please select' option" + assert @response.body.include?("
    <%= t('org_admin.user_full_name') %><%= t('org_admin.user_name') %><%= t('org_admin.last_logged_in') %><%= t('org_admin.how_many_plans') %><%= t('org_admin.privileges') %><%= _('Name') %><%= _('Email address') %><%= _('Last logged in') %><%= _('How many plans?') %><%= _('Privileges') %>
    - <% if !user.project_groups.nil? then%> - <%= user.project_groups.length %> + <% if !user.roles.nil? then%> + <%= user.roles.length %> <% end %> <% unless current_user == user %> - <% b_label = t('helpers.submit.edit')%> + <% b_label = _('Edit')%> <%= link_to b_label, admin_grant_permissions_user_path(user), :class => "dmp_table_link"%> <% end %> ' + I18n.t("helpers.submit.cancel") + '' + __('Cancel') + '
    ' + I18n.t("helpers.project.filter.no_matches") + '
    ' + __('No matches') + '