diff --git a/app/controllers/api/v0/guidance_groups_controller.rb b/app/controllers/api/v0/guidance_groups_controller.rb index ce2ac72..65899b9 100644 --- a/app/controllers/api/v0/guidance_groups_controller.rb +++ b/app/controllers/api/v0/guidance_groups_controller.rb @@ -4,12 +4,6 @@ before_action :authenticate #after_action :verify_authorized - def show - @guidance_group = GuidanceGroup.find(params[:id]) - raise Pundit::NotAuthorizedError unless Api::V0::GuidanceGroupPolicy.new(@user, @guidance_group).show? - respond_with @guidance_group - end - def index raise Pundit::NotAuthorizedError unless Api::V0::GuidanceGroupPolicy.new(@user, :guidance_group).index? @all_viewable_groups = GuidanceGroup.all_viewable(@user) diff --git a/app/controllers/api/v0/guidances_controller.rb b/app/controllers/api/v0/guidances_controller.rb deleted file mode 100644 index b6866d2..0000000 --- a/app/controllers/api/v0/guidances_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -module Api - module V0 - class GuidancesController < Api::V0::BaseController - before_action :authenticate - #after_action :verify_authorized - - ## - # returns the specified guidance - def show - @guidance = Guidance.find(params[:id]) - raise Pundit::NotAuthorizedError unless Api::V0::GuidancePolicy.new(@user, @guidance).show? - respond_with get_resource - end - - ## - # returns all guidances viewable to a user - def index - authorize Guidance - raise Pundit::NotAuthorizedError unless Api::V0::GuidancePolicy.new(@user, :guidance).index? - respond_with @all_viewable_guidances - end - - ## - # defines the default pundit user (overwrites current_user) - def pundit_user - @user - end - - - private - def query_params - params.permit(:id) - end - end - end -end diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index b0f3465..f967326 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -359,7 +359,7 @@ begin @exported_plan.save! - file_name = @plan.title.gsub(/ /, "_") + file_name = @exported_plan.settings(:export)[:value]['title'].gsub(/ /, "_") respond_to do |format| format.html diff --git a/app/views/answers/_new_edit.html.erb b/app/views/answers/_new_edit.html.erb index 54fa9b4..2434033 100644 --- a/app/views/answers/_new_edit.html.erb +++ b/app/views/answers/_new_edit.html.erb @@ -2,7 +2,7 @@ This partial creates a form for each type of question. The local variables are: plan, answer, question, readonly --> <% q_format = question.question_format %> -<%= semantic_form_for answer, :url => {controller: :answers, action: :update }, html: {method: "put", class: "roadmap-form"}, remote: true do |f| %> +<%= 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 } %> @@ -74,7 +74,7 @@

<%= raw(answer.text) %>

<% else %> <%= text_area_tag('answer[text]', answer.text, id: "answer-text-#{question.id}") %> - <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.change_answer") %> + <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.tinymce_answer_events", content_css: asset_path('application.css')) %> <% end %> <%end%> <% end %> @@ -90,7 +90,7 @@

<%= raw(answer.text) %>

<% else %> <%= text_area_tag('answer[text]', answer.text, id: "answer-text-#{question.id}") %> - <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.change_answer") %> + <%= tinymce(selector: "#answer-text-#{question.id}", setup: "$.fn.tinymce_answer_events", content_css: asset_path('application.css')) %> <% end %> <% end %> 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 d1b0a2e..0000000 --- a/app/views/api/v0/guidance_groups/show.json.jbuilder +++ /dev/null @@ -1,14 +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 - - 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 ac98f0a..0000000 --- a/app/views/api/v0/guidances/index.json.jbuilder +++ /dev/null @@ -1,22 +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_group = guidance.guidance_group - unless guidance_group.nil? - json.guidance_group do - json.name guidance_group.name - json.id guidance_group.id - - json.optional guidance_group.optional_subset - json.updated guidance_group.updated_at - end - 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 67d3385..0000000 --- a/app/views/api/v0/guidances/show.json.jbuilder +++ /dev/null @@ -1,22 +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 one guidance group - guidance_group = @guidance.guidance_group - - unless guidance_group.nil? - json.guidance_group do - json.name guidance_group.name - json.id guidance_group.id - - 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/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index a9c5b2f..8bb0f82 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -115,18 +115,3 @@ <% end %> - - - - diff --git a/app/views/guidances/_add_guidance.html.erb b/app/views/guidances/_add_guidance.html.erb index da1d7ca..bd036d2 100644 --- a/app/views/guidances/_add_guidance.html.erb +++ b/app/views/guidances/_add_guidance.html.erb @@ -63,7 +63,7 @@
- <%= tinymce %> + <%= tinymce :content_css => asset_path('application.css') %> <% end %> diff --git a/app/views/guidances/admin_edit.html.erb b/app/views/guidances/admin_edit.html.erb index 1a04cc8..b8ddce7 100644 --- a/app/views/guidances/admin_edit.html.erb +++ b/app/views/guidances/admin_edit.html.erb @@ -82,7 +82,7 @@
- <%= tinymce %> + <%= tinymce :content_css => asset_path('application.css') %> <%end%> diff --git a/app/views/guidances/admin_new.html.erb b/app/views/guidances/admin_new.html.erb index f77a3f6..59b5397 100644 --- a/app/views/guidances/admin_new.html.erb +++ b/app/views/guidances/admin_new.html.erb @@ -79,7 +79,7 @@
- <%= tinymce %> + <%= tinymce :content_css => asset_path('application.css') %> <%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) %> +
+
+
+ +
diff --git a/app/views/orgs/admin_edit.html.erb b/app/views/orgs/admin_edit.html.erb index adbc664..3bbc468 100644 --- a/app/views/orgs/admin_edit.html.erb +++ b/app/views/orgs/admin_edit.html.erb @@ -79,5 +79,5 @@ -<%= tinymce %> +<%= tinymce :content_css => asset_path('application.css') %> diff --git a/app/views/phases/_add_note.html.erb b/app/views/phases/_add_note.html.erb deleted file mode 100644 index 5a20c05..0000000 --- a/app/views/phases/_add_note.html.erb +++ /dev/null @@ -1,24 +0,0 @@ - - -<% - 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 %> - -
-<% end %> diff --git a/app/views/phases/_answer_form.html.erb b/app/views/phases/_answer_form.html.erb index dfa1d6c..c95732b 100644 --- a/app/views/phases/_answer_form.html.erb +++ b/app/views/phases/_answer_form.html.erb @@ -18,7 +18,7 @@ end %>
-
">
+
" class="answer-locking">
"> <%= render(partial: 'answers/new_edit', locals: { question: question, answer: answer, readonly: readonly }) %>
@@ -34,42 +34,30 @@
<% 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? %> - - <% css_style_comment_div = "display: none;"%> - <% css_style_guidance_div = ""%> -
  • - <%= link_to _('Guidance'), "#", class: "guidance_accordion_button" %> -
  • -
  • - <% if comments.count > 0%> - <% comments_label_with_count = "#{_('Notes')} (#{comments.count})"%> - <%= link_to comments_label_with_count , "#", id: "notes_number_#{question.id}", class: "comments_accordion_button" %> + <% 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: "comments_accordion_button" %> + <%= link_to _('Share note'), "#", id: "notes_number_#{question.id}", class: "right_column_tab_link" %> <% end %>
  • - <% else %> - - <% css_style_comment_div = ""%> - <% css_style_guidance_div = "display: none;"%> -
  • - <% if comments.count > 0 %> - <% comments_label_with_count = "#{_('Notes')} (#{comments.count})"%> -

    <%= comments_label_with_count %>

    - <% else %> -

    <%= _('Share note') %>

    - <% end %> -
  • - <% end %>
- -
+ +
@@ -120,9 +108,9 @@ <% end %>
-
- -
+
+ +
<%= render partial: "note", locals: {question: question, answer: answer, plan: plan, suffix: "" }%>
diff --git a/app/views/phases/_archive_note.html.erb b/app/views/phases/_archive_note.html.erb deleted file mode 100644 index 0e7b244..0000000 --- a/app/views/phases/_archive_note.html.erb +++ /dev/null @@ -1,21 +0,0 @@ - -<%= 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 => "/phases/view_note", 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/phases/_edit_note.html.erb b/app/views/phases/_edit_note.html.erb deleted file mode 100644 index 17a75bc..0000000 --- a/app/views/phases/_edit_note.html.erb +++ /dev/null @@ -1,15 +0,0 @@ - - -<%= 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/phases/_list_notes.html.erb b/app/views/phases/_list_notes.html.erb deleted file mode 100644 index 56a8b96..0000000 --- a/app/views/phases/_list_notes.html.erb +++ /dev/null @@ -1,85 +0,0 @@ - - -<% 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 => "/phases/view_note", locals: {note: latest_note} %> -
-
-<%end%> - -<%notes.each do |note|%> - - - - - - - - - -<%end%> diff --git a/app/views/phases/_note.html.erb b/app/views/phases/_note.html.erb index 5cc8df3..c296d9b 100644 --- a/app/views/phases/_note.html.erb +++ b/app/views/phases/_note.html.erb @@ -1,6 +1,3 @@ - - <% if answer.present? && answer.notes.any? %> <% notes = answer.notes.all.to_a.sort! {|x,y| y.updated_at <=> x.updated_at } %> <% questionid = question.id %> @@ -18,15 +15,15 @@
- <%= render :partial => "/phases/list_notes", locals: {question_id: question.id, notes: notes, plan: plan} %> + <%= render :partial => "/notes/list", locals: {question_id: question.id, notes: notes, plan: plan} %>
<% else%> - <%= render :partial => "/phases/add_note", locals: {answer: answer, question: question, plan_id: plan.id }%> + <%= 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/_show_phase.html.erb b/app/views/phases/_show_phase.html.erb deleted file mode 100644 index ecb5dd4..0000000 --- a/app/views/phases/_show_phase.html.erb +++ /dev/null @@ -1,37 +0,0 @@ - - -

- <%= _('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/_view_note.html.erb b/app/views/phases/_view_note.html.erb deleted file mode 100644 index 0610f0c..0000000 --- a/app/views/phases/_view_note.html.erb +++ /dev/null @@ -1,11 +0,0 @@ - -<% user = User.find(note.user_id) %> -
-
-
-
    -
  • <%= _('Noted by:')%>

  • -
  • <%= user.name%> (<%= l note.updated_at, format: :custom %>)
  • -
  • <%= raw note.text %>
  • -
-
diff --git a/app/views/phases/admin_add.html.erb b/app/views/phases/admin_add.html.erb index 72a9a66..546c727 100644 --- a/app/views/phases/admin_add.html.erb +++ b/app/views/phases/admin_add.html.erb @@ -50,7 +50,7 @@
<%= text_area_tag("phase-desc","" , class: "tinymce") %> - <%= 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."))%> diff --git a/app/views/phases/admin_show.html.erb b/app/views/phases/admin_show.html.erb index 321ac60..60dc90d 100644 --- a/app/views/phases/admin_show.html.erb +++ b/app/views/phases/admin_show.html.erb @@ -2,7 +2,7 @@ <%= stylesheet_link_tag "admin" %> <% javascript 'admin.js' %> -<%= tinymce %> +<%= tinymce :content_css => asset_path('application.css') %>

<%= @phase.template.title %> diff --git a/app/views/phases/edit.html.erb b/app/views/phases/edit.html.erb index 8ddbcc2..5a4c267 100644 --- a/app/views/phases/edit.html.erb +++ b/app/views/phases/edit.html.erb @@ -1,6 +1,7 @@ <%- model_class = Plan -%> -<% javascript "plans.js" %> -<% javascript "answers/status.js" %> +<% javascript('plans.js') %> +<% javascript('answers/status.js') %> +<% javascript ('notes/index.js') %> - <% if session[:question_id_comments].to_i != 0 then %> - <% question_from_comment = Question.find(session[:question_id_comments])%> - <% if sectionid == question_from_comment.section_id then %> - <%= hidden_field_tag :comment_section_id, question_from_comment.section_id, :class => "comment_section_id" %> - <%end%> - <% end%> -
@@ -123,6 +116,3 @@
<%= render :partial => "plans/export", locals: {plan: @plan, plan_data: @plan_data, phase: @phase } %> - - -<% session.delete(:question_id_comments)%> diff --git a/app/views/plans/_plan_details.html.erb b/app/views/plans/_plan_details.html.erb index ee420d1..f971214 100644 --- a/app/views/plans/_plan_details.html.erb +++ b/app/views/plans/_plan_details.html.erb @@ -1,3 +1,4 @@ +<% javascript('plans/edit.js') %>
@@ -77,7 +78,7 @@
- <%= _('Edit plan details') %> +
diff --git a/app/views/plans/edit.html.erb b/app/views/plans/edit.html.erb index 44393fa..96cfa9c 100644 --- a/app/views/plans/edit.html.erb +++ b/app/views/plans/edit.html.erb @@ -143,7 +143,7 @@
<% end %>
- <%= tinymce %> + <%= tinymce :content_css => asset_path('application.css') %>

<%= _('Export') %> diff --git a/app/views/plans/export.docx.erb b/app/views/plans/export.docx.erb index 7f9c2c2..be267a8 100644 --- a/app/views/plans/export.docx.erb +++ b/app/views/plans/export.docx.erb @@ -1,4 +1,4 @@ -

<%= @exported_plan.title %>

+

<%= @plan.title %>

<%= @plan.template.title %>

<% details = @exported_plan.admin_details %> diff --git a/app/views/plans/share.html.erb b/app/views/plans/share.html.erb index 42f6988..3c3f301 100644 --- a/app/views/plans/share.html.erb +++ b/app/views/plans/share.html.erb @@ -1,5 +1,5 @@ <%- model_class = Plan -%> - +<% javascript('plans/share.js') %> <%= render :partial => "plan_title", locals: {plan: @plan} %> @@ -35,7 +35,7 @@ <% else %> <%= form_for role, url: {controller: :roles, action: :update, id: role.id }, html: {method: :put} do |f| %>
- <%= f.select :access_level, {"#{_('Co-owner')}": 3, "#{_('Editor')}": 2, "#{_('Read only')}": 1}, {}, {id: "#{role.id}-can-edit", class: "toggle-existing-user-access has-tooltip", 'data-toggle': "tooltip", 'title': _('Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access.') } %> + <%= f.select :access_level, {"#{_('Co-owner')}": 3, "#{_('Editor')}": 2, "#{_('Read only')}": 1}, {}, {id: "#{role.id}-can-edit", class: "toggle-access-level has-tooltip", 'data-toggle': "tooltip", 'title': _('Editors can contribute to plans. Co-owners have additional rights to edit plan details and control access.') } %>
<% end %> <% end %> diff --git a/app/views/question_options/_option_fields.html.erb b/app/views/question_options/_option_fields.html.erb index aa361f3..1d00634 100644 --- a/app/views/question_options/_option_fields.html.erb +++ b/app/views/question_options/_option_fields.html.erb @@ -3,5 +3,8 @@ <%= 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 %><%= _('Remove') %> + + <%= f.hidden_field :_destroy %> + <%= _('Remove') %> + diff --git a/app/views/questions/_add_question.html.erb b/app/views/questions/_add_question.html.erb index ae1617b..96b894f 100644 --- a/app/views/questions/_add_question.html.erb +++ b/app/views/questions/_add_question.html.erb @@ -26,7 +26,8 @@ <%= _('Question text')%> - <%= f.text_area :text, rows: "5", id: "new_question_text_#{section.id}" %> + + <%= text_area_tag('question[text]', "", id: "new_question_text_#{section.id}", class: "tinymce") %>
diff --git a/app/views/questions/_edit_question.html.erb b/app/views/questions/_edit_question.html.erb index 919ff46..c46d932 100644 --- a/app/views/questions/_edit_question.html.erb +++ b/app/views/questions/_edit_question.html.erb @@ -20,7 +20,8 @@ <%= _('Question text')%> - <%= f.text_area :text, rows: "5" %> + + <%= f.text_area(:text, class: "tinymce") %>
diff --git a/app/views/shared/_register_form.html.erb b/app/views/shared/_register_form.html.erb index ab2f719..1546594 100644 --- a/app/views/shared/_register_form.html.erb +++ b/app/views/shared/_register_form.html.erb @@ -1,4 +1,4 @@ -<% javascript "shared/register_form.js" %> +<% javascript('shared/register_form.js') %> <%= form_for(resource, :as => "user", :url => registration_path("user"), :htmlb => {:autocomplete =>"off"}, :html => {class: "roadmap-form"}) do |f| %>
    diff --git a/app/views/templates/admin_new.html.erb b/app/views/templates/admin_new.html.erb index e180b4a..bfdf195 100644 --- a/app/views/templates/admin_new.html.erb +++ b/app/views/templates/admin_new.html.erb @@ -45,4 +45,4 @@ <% end %>
-<%= tinymce %> \ No newline at end of file +<%= 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 index 77b956a..75564de 100644 --- a/app/views/templates/admin_template.html.erb +++ b/app/views/templates/admin_template.html.erb @@ -59,4 +59,4 @@ <% end %> -<%= tinymce %> +<%= tinymce :content_css => asset_path('application.css') %> diff --git a/config/application.rb b/config/application.rb index 5693427..96f8c18 100644 --- a/config/application.rb +++ b/config/application.rb @@ -68,8 +68,7 @@ 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) @@ -80,9 +79,14 @@ 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 diff --git a/config/tinymce.yml b/config/tinymce.yml index 2b2bb03..8002f2e 100644 --- a/config/tinymce.yml +++ b/config/tinymce.yml @@ -1,15 +1,15 @@ -content_css: /assets/application.css selector: 'textarea.tinymce' statusbar: false menubar: false toolbar: bold italic | bullist numlist | link | table plugins: - table - #- autoresize + - autoresize - link - paste -target_list: false +target_list: false autoresize_min_height: 130 +autoresize_bottom_margin: 10 extended_valid_elements: "iframe[tooltip] , a[href|target=_blank]" extended_valid_elements: "a[href|target=_blank]" paste_auto_cleanup_on_paste : true @@ -18,4 +18,6 @@ paste_convert_middot_lists: true paste_remove_styles_if_webkit: true paste_remove_spans: true -paste_strip_class_attributes: "all" \ No newline at end of file +paste_strip_class_attributes: "all" +table_default_attributes: + border: 1 \ No newline at end of file diff --git a/lib/assets/javascripts/Dmproadmap.js b/lib/assets/javascripts/Dmproadmap.js new file mode 100644 index 0000000..2799439 --- /dev/null +++ b/lib/assets/javascripts/Dmproadmap.js @@ -0,0 +1,35 @@ +window.DMPROADMAP = (function(){ + return { + /* + Delays invoking of the function passed until after wait milliseconds have elapsed since + the last time the debounced function was invoked. + @param {function} func - the function to execute later on + @param {number} wait - the number of milliseconds to wait until func is executed + @returns The debounced function. It comes with a cancel method to cancel delayed func invocation + */ + debounce: function(func, wait){ + var timeoutID = null; + function cancel() { + if(timeoutID !== null){ + clearTimeout(timeoutID); + return true; + } + return false; + } + return (function() { + var debounced = function() { + var ctx = this; + var args = arguments; + var later = function() { + timeoutID = null; + func.apply(ctx, args); + } + clearTimeout(timeoutID); + timeoutID = setTimeout(later, wait || 5000); + } + debounced.cancel = cancel; + return debounced; + })(); + } + }; +})(); \ No newline at end of file diff --git a/lib/assets/javascripts/admin.js b/lib/assets/javascripts/admin.js index 7b47b6b..4dc2829 100644 --- a/lib/assets/javascripts/admin.js +++ b/lib/assets/javascripts/admin.js @@ -7,7 +7,45 @@ $( document ).ready(function() { + /*---------------- + Listener for removing a question_option for option_based questions + Note the usage of event-delegation approach through the presence of the selector (e.g. .remove-option) which means the handler + is ONLY called when the event occurs at .remove-option and has the advantage of processing events from descendant elements (e.g. tr class="options_content") + that are added to the document at a later time + ------------------*/ + $('.options_table').on('click','.remove-option', function(e){ + e.preventDefault(); + $(this).prev().val(true); + $(this).closest('.options_content').hide(); + }); + /*---------------- + Listener for adding a question_option for option_based questions + ------------------*/ + $(".add-option").click(function(e){ + e.preventDefault(); + var tbl = $(this).parent().find("table.options_table > tbody.options_tbody"), + last = tbl.find("tr:last"), + clone = last.clone(); + nbr = parseInt(last.find(".number_field").val()); + + // Update the input field names and ids + clone.find("input").each(function(index){ + $(this).prop("id", $(this).prop("id").replace(/_\d+_/g, "_" + nbr + "_")); + $(this).prop("name", $(this).prop("name").replace(/\[\d+\]/g, "[" + nbr + "]")); + }); + + // Remove the hidden class and make sure the new row is not marked for removal + clone.removeClass('hidden'); + clone.find("[id$=" + nbr + "__destroy]").val(false); + + // Default the other values + clone.find("[id$=" + nbr + "_number]").val("" + (nbr + 1)); + clone.find("[id$=" + nbr + "_text]").val(""); + clone.find("[id$=" + nbr + "_is_default]").prop("checked", false); + + last.after(clone); + }); if($('.in').length > 0) { if ($('.in .current_question').length > 0) { $(document.body).animate({ @@ -107,7 +145,7 @@ //if question text area is empty send alert $('.new_question_save_button').click(function(e){ var s_id = $(this).prev(".section_id").val(); - if ($('#new_question_text_'+ s_id).val() == ''){ + if ($('#new_question_text_'+ s_id).tinymce().getContent() === ''){ alert(__('Question text is empty, please enter your question.')); return false; } diff --git a/lib/assets/javascripts/answers/status.js b/lib/assets/javascripts/answers/status.js index ebf5165..0abee0e 100644 --- a/lib/assets/javascripts/answers/status.js +++ b/lib/assets/javascripts/answers/status.js @@ -1,27 +1,86 @@ //= require jquery.timeago.js $(document).ready(function(){ - $("form.answer").submit(function(){ + /*-------------- + START Autosaving + ----------------*/ + // debounced object holds a set of debounced functions, one for each form present in the page. Note, + // each debounced function stored at funcs is created on demand, i.e. once the user changes any element of a form + var debounced = (function(){ + var funcs = {}; + return { + has: function(id){ + return funcs[id] !== undefined; + }, + get: function(id){ + + return funcs[id]; + }, + set: function(id, func){ + funcs[id] = DMPROADMAP.debounce(func, 5000); + } + } + })(); + // This function triggers a form submit, if and only if the answer has not been optimistically locked + function autoSaving(){ + if($(this).closest('.question-form').find('.answer-locking').children().length === 0){ + $(this).closest('form.answer').submit(); + } + }; + /*-------------- + END Autosaving + ----------------*/ + // Listener for submit event triggered + $('.question-form').on('submit', 'form.answer', function(){ + var id = $(this).attr('data-autosave'); + if(debounced.has(id)){ + debounced.get(id).cancel(); //Cancels the execution of its debounced function, if not already, since submit() could have been trigerred through Save button + } var container = $(this).closest('.question-form'); var saving = container.find('.saving-message'); saving.show(); }); - $("form.answer fieldset input, form.answer fieldset select").change(function(){ + // Listener for changes at any element value from question-form + $('.question-form').on('change', 'form.answer fieldset input, form.answer fieldset select', function(){ var unsaved = $(this).closest('.question-form').find('.answer-unsaved'); unsaved.show(); var notAnswered = $(this).closest('.question-form').find('.not-answered'); notAnswered.hide(); }); - $.fn.change_answer = function(editor){ - editor.on('change', function(event){ + // Listener for changes at any element value from question-form. This triggers the debounced function + $('.question-form').on('change', 'form.answer fieldset input, form.answer fieldset select', function(){ + var id = $(this).closest('form.answer').attr('data-autosave'); + if(!debounced.has(id)){ + debounced.set(id, autoSaving); + } + debounced.get(id).apply($(this),[id]); + }); + // Function bounded to Jquery scope that setup event handlers for tinymce instances + $.fn.tinymce_answer_events = function(editor){ + editor.on('change', function(){ var unsaved = $('#'+editor.id).closest('.question-form').find('.answer-unsaved'); unsaved.show(); var notAnswered = $('#'+editor.id).closest('.question-form').find('.not-answered'); notAnswered.hide(); }); + editor.on('blur', function(){ + var id = $('#'+editor.id).closest('form.answer').attr('data-autosave'); + $('#'+editor.id).val($('#'+editor.id).tinymce().getContent()); // Forces Updating content textarea with the value from tinymce + if(!debounced.has(id)){ + debounced.set(id, autoSaving); + } + debounced.get(id).apply($('#'+editor.id),[id]); + }); + editor.on('focus', function(){ + var id = $('#'+editor.id).closest('form.answer').attr('data-autosave'); + if(debounced.has(id)){ + debounced.get(id).cancel(); //Cancels the execution of its debounced function either because user transitioned from question with options + // to the comments or because textarea lost focus and gained again before the delay being met + } + }); } $.fn.init_answer_status = function() { - $('abbr.timeago').timeago(); + $('abbr.timeago').timeago(); //TODO examine if possible refactoring as event-delegated } $.fn.init_answer_status(); }); \ No newline at end of file diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js index 3f45565..d746c75 100644 --- a/lib/assets/javascripts/application.js +++ b/lib/assets/javascripts/application.js @@ -22,173 +22,5 @@ //= require_tree ./locale //= require gettext/all //= require jquery-accessible-autocomplet-list-aria.js - - -$( document ).ready(function() { - - $(function(){ - $('.dropdown-toggle').dropdown() - }); - - $('.accordion-body').on('show', function() { - var plus = $(this).parent().children(".accordion-heading").children(".accordion-toggle").children(".icon-plus").removeClass("icon-plus").addClass("icon-minus"); - }).on('hide', function(){ - var minus = $(this).parent().children(".accordion-heading").children(".accordion-toggle").children(".icon-minus").removeClass("icon-minus").addClass("icon-plus"); - }); - - //accordion home page - $('.accordion-home').on('show', function() { - var plus = $(this).parent().find(".plus-laranja").removeClass("plus-laranja").addClass("minus-laranja"); - }).on('hide', function(){ - var minus = $(this).parent().find(".minus-laranja").removeClass("minus-laranja").addClass("plus-laranja"); - }); - - //accordion project details page when project has more than 1 plan - $('.accordion-project').on('show', function() { - var plus = $(this).parent().children(".accordion-heading").find(".plus-laranja").removeClass("plus-laranja").addClass("minus-laranja"); - }).on('hide', function(){ - var minus = $(this).parent().children(".accordion-heading").find(".minus-laranja").removeClass("minus-laranja").addClass("plus-laranja"); - }); - - $('.export-format-selection').click(function(e){ - e.preventDefault(); - if($(this).val() == 'pdf'){ - $('#pdf-format-options').show(); - }else{ - $('#pdf-format-options').hide(); - } - }); - - //$('#3-or-4-splash').modal(); - - $('.typeahead').select2({ - width: "element", - allowClear: true - }); - - $(".help").popover(); - - $('.has-tooltip').tooltip({ - placement: "right", - trigger: "focus" - }); - - $(".show-edit-toggle").click(function (e) { - e.preventDefault(); - - $(".edit-plan-details").toggle(); - $(".show-plan-details").toggle(); - }); - - $(".toggle-existing-user-access").change(function(){ - $(this).closest("form").submit(); - }); - - $('#user_organisation_id').on("change", function(e) { - e.preventDefault(); - var selected_org = $(this).select2("val"); - var other_orgs = $("#other-organisation-name").attr("data-orgs").split(","); - var index = $.inArray(selected_org, other_orgs); - if (index > -1) { - $("#other-organisation-name").show(); - $("#user_other_organisation").focus(); - } - else { - $("#other-organisation-name").hide(); - } - }); - - $("#other-org-link > a").click(function(e){ - e.preventDefault(); - var other_org = $("#other-organisation-name").attr("data-orgs").split(","); - $("#user_organisation_id").select2("val", other_org); - $("#other-org-link").hide(); - $("#user_organisation_id").change(); - }); - - //alert dialog for unlink Shibbileth account - $("#unlink-institutional-credentials-dialog").on("show", function(){ - $('.select2-choice').hide(); - }); - - $("#unlink-shibboleth-cancelled").click(function (){ - $("#unlink-institutional-credentials-dialog").modal("hide"); - $('.select2-choice').show(); - }); - - $("#unlink-shibboleth-confirmed").click(function (){ - $("#unlink_flag").val('true'); - $("#edit_user").submit(); - - }); - - //Question Options - // --------------------------------------------------------------------------- - $(".options_table").on("click", ".remove-option", function(e){ - e.preventDefault(); - - // Mark the option for removal - $($(this).siblings()[0]).val(true); - - // Hide the entire table row and the associated hidden field for the item - $(this).parent().parent().addClass('hidden'); - }); - - $(".add-option").click(function(e){ - e.preventDefault(); - - var tbl = $(this).parent().find("table.options_table > tbody.options_tbody"), - last = tbl.find("tr:last"), - clone = last.clone(); - nbr = parseInt(last.find(".number_field").val()); - - // Update the input field names and ids - clone.find("input").each(function(index){ - $(this).prop("id", $(this).prop("id").replace(/_\d+_/g, "_" + nbr + "_")); - $(this).prop("name", $(this).prop("name").replace(/\[\d+\]/g, "[" + nbr + "]")); - }); - - // Remove the hidden class and make sure the new row is not marked for removal - clone.removeClass('hidden'); - clone.find("[id$=" + nbr + "__destroy]").val(false); - - // Default the other values - clone.find("[id$=" + nbr + "_number]").val("" + (nbr + 1)); - clone.find("[id$=" + nbr + "_text]").val(""); - clone.find("[id$=" + nbr + "_is_default]").prop("checked", false); - - last.after(clone); - }); - - /*$('#continue-to-new').click(function(e){ - var destination = $(this).attr("href"); - var n = destination.lastIndexOf('='); - destination = decodeURIComponent(destination.substring(n + 1)); - $.post('splash_logs', {destination: destination} ); - $("#3-or-4-splash").modal('hide'); - return false; - });*/ - -}); - -// --------------------------------------------------------------------------- -function selectItemsFromJsonArray(array, selector, array_of_values, callback){ - var out = []; - - if(!Array.isArray(array_of_values)){ - array_of_values = [array_of_values]; - } - - for(var i = 0; i < array.length; i++){ - if(array_of_values.indexOf('' + array[i][selector]) >= 0){ - out.push(array[i]); - } - } - - var selectItemsFromJsonArrayInterval = setInterval(function(){ - if(i >= array.length){ - clearInterval(selectItemsFromJsonArrayInterval); - callback(out); - } - }, 50); -} +//= require bootstrap_listeners.js +//= require Dmproadmap.js \ No newline at end of file diff --git a/lib/assets/javascripts/bootstrap_listeners.js b/lib/assets/javascripts/bootstrap_listeners.js new file mode 100644 index 0000000..409805d --- /dev/null +++ b/lib/assets/javascripts/bootstrap_listeners.js @@ -0,0 +1,23 @@ +$(document).ready(function(){ + $('.accordion-body').on('show.bs.collapse', function(){ + $(this).parent().find('.icon-plus').removeClass('icon-plus').addClass('icon-minus'); + }).on('hide.bs.collapse', function(){ + $(this).parent().find('.icon-minus').removeClass('icon-minus').addClass('icon-plus'); + }); + $('.accordion-home').on('show', function() { + $(this).parent().find('.plus-laranja').removeClass('plus-laranja').addClass('minus-laranja'); + }).on('hide', function(){ + $(this).parent().find('.minus-laranja').removeClass('minus-laranja').addClass('plus-laranja'); + }); + $('.accordion-project').on('show', function() { + $(this).parent().find('.plus-laranja').removeClass('plus-laranja').addClass('minus-laranja'); + }).on('hide', function(){ + $(this).parent().find('.minus-laranja').removeClass('minus-laranja').addClass('plus-laranja'); + }); + // Initialises all tooltips present on a page + $('.has-tooltip').tooltip({ + placement: "right", + trigger: "focus" + }); + $(".help").popover(); +}); \ No newline at end of file diff --git a/lib/assets/javascripts/export_configure.js b/lib/assets/javascripts/export_configure.js index d05864b..2229eee 100644 --- a/lib/assets/javascripts/export_configure.js +++ b/lib/assets/javascripts/export_configure.js @@ -105,4 +105,15 @@ }); }); }); + /*---------------- + Listener for select that displays the formatting options (e.g. csv, html, pdf, txt, etc.) + ------------------*/ + $('.export-format-selection').click(function(e){ + e.preventDefault(); + if($(this).val() === 'pdf'){ + $('#pdf-format-options').show(); + }else{ + $('#pdf-format-options').hide(); + } + }); }); diff --git a/lib/assets/javascripts/notes/index.js b/lib/assets/javascripts/notes/index.js new file mode 100644 index 0000000..dfcb5b2 --- /dev/null +++ b/lib/assets/javascripts/notes/index.js @@ -0,0 +1,77 @@ +// the "add note" button +/*---------------- + Invoked at app/views/phases/_note.html.erb L.14 +------------------*/ +function add_note_button(q_id){ + $(".alert-notice").hide(); + $('.view_comment_class').hide(); + $('.edit_comment_class').hide(); + $('.archive_comment_class').hide(); + //$('#add_comment_button_bottom_div_'+ q_id).hide(); + $('#add_comment_button_top_div_'+ q_id).hide(); + //$('#{questionid}new_note_text').text(""); + $('#add_comment_block_div_'+ q_id).show(); +} + +// the "view" link +/*---------------- + Invoked at app/views/phases/_list_notes.html.erb L.34 +------------------*/ +function view_note_button(c_id, q_id){ + $(".alert-notice").hide(); + $('.view_comment_class').hide(); + $('.edit_comment_class').hide(); + $('.archive_comment_class').hide(); + $('#lastet_comment_div_'+ q_id).hide(); + $('#edit_comment_div_'+ c_id).hide(); + $('#archive_comment_div_'+ c_id).hide(); + $('#add_comment_block_div_'+ q_id).hide(); + $('#view_comment_div_'+ c_id).show(); + $('#add_comment_button_top_div_'+ q_id).show(); +} + + +// the "edit" link +/*---------------- + Invoked at app/views/phases/_list_notes.html.erb L.37 +------------------*/ +function edit_note(c_id, q_id){ + $('.edit_comment_class').hide(); + $('.view_comment_class').hide(); + $('.archive_comment_class').hide(); + $('#lastet_comment_div_'+ q_id).hide(); + $('#view_comment_div_'+ c_id).hide(); + $('#archive_comment_div_'+ c_id).hide(); + $('#add_comment_block_div_'+ q_id).hide(); + $('#edit_comment_div_'+ c_id).show(); + $('#add_comment_button_top_div_'+ q_id).show(); +} + + +//the "remove" link +/*---------------- + Invoked at app/views/phases/_archive_note.html.erb L.17 + Invoked at app/views/phases/_list_notes.html.erb L.38 + Invoked at app/views/phases/_list_notes.html.erb L.43 +------------------*/ +function archive_note(c_id, q_id){ + $('.edit_comment_class').hide(); + $('.view_comment_class').hide(); + $('.archive_comment_class').hide(); + $('#view_comment_div_'+ c_id).hide(); + $('#lastet_comment_div_'+ q_id).hide(); + $('#edit_comment_div_'+ c_id).hide(); + $('#add_comment_block_div_'+ q_id).hide(); + $('#archive_comment_div_'+ c_id).show() + $('#add_comment_button_top_div_'+ q_id).show(); +} + +// cancel remove +/*---------------- + Invoked at app/views/phases/_archive_note.html.erb L.18 +------------------*/ +function cancel_archive_note(c_id) { + var c_id = $(this).prev(".comment_id").val(); + $('.archive_comment_class').hide(); + $('#view_comment_div_'+ c_id).show(); +} \ No newline at end of file diff --git a/lib/assets/javascripts/plans.js b/lib/assets/javascripts/plans.js index 5837312..8f0762a 100644 --- a/lib/assets/javascripts/plans.js +++ b/lib/assets/javascripts/plans.js @@ -1,149 +1,7 @@ - - -var dirty = {}; - - - -// functions added to buttons and links in the notes section of the answer form - -// the "add note" button -function add_note_button(q_id){ - $(".alert-notice").hide(); - $('.view_comment_class').hide(); - $('.edit_comment_class').hide(); - $('.archive_comment_class').hide(); - //$('#add_comment_button_bottom_div_'+ q_id).hide(); - $('#add_comment_button_top_div_'+ q_id).hide(); - //$('#{questionid}new_note_text').text(""); - $('#add_comment_block_div_'+ q_id).show(); -} - -// the "view" link -function view_note_button(c_id, q_id){ - $(".alert-notice").hide(); - $('.view_comment_class').hide(); - $('.edit_comment_class').hide(); - $('.archive_comment_class').hide(); - $('#lastet_comment_div_'+ q_id).hide(); - $('#edit_comment_div_'+ c_id).hide(); - $('#archive_comment_div_'+ c_id).hide(); - $('#add_comment_block_div_'+ q_id).hide(); - $('#view_comment_div_'+ c_id).show(); - $('#add_comment_button_top_div_'+ q_id).show(); -} - - -// the "edit" link -function edit_note(c_id, q_id){ - $('.edit_comment_class').hide(); - $('.view_comment_class').hide(); - $('.archive_comment_class').hide(); - $('#lastet_comment_div_'+ q_id).hide(); - $('#view_comment_div_'+ c_id).hide(); - $('#archive_comment_div_'+ c_id).hide(); - $('#add_comment_block_div_'+ q_id).hide(); - $('#edit_comment_div_'+ c_id).show(); - $('#add_comment_button_top_div_'+ q_id).show(); -} - - -//the "remove" link -function archive_note(c_id, q_id){ - $('.edit_comment_class').hide(); - $('.view_comment_class').hide(); - $('.archive_comment_class').hide(); - $('#view_comment_div_'+ c_id).hide(); - $('#lastet_comment_div_'+ q_id).hide(); - $('#edit_comment_div_'+ c_id).hide(); - $('#add_comment_block_div_'+ q_id).hide(); - $('#archive_comment_div_'+ c_id).show() - $('#add_comment_button_top_div_'+ q_id).show(); -} - -// cancel remove -function cancel_archive_note(c_id) { - var c_id = $(this).prev(".comment_id").val(); - $('.archive_comment_class').hide(); - $('#view_comment_div_'+ c_id).show(); -} - - - - -// adding functionality on page load - -$( document ).ready(function() { - - //reload page back to where it was before committing comment - - if($('#comment_section_id').length) { - var section_id = $('#comment_section_id').val(); - - $("#collapse-" + section_id).addClass("in"); - $("#collapse-" + section_id).children(".accordion-inner").find(".loading").show(); - $("#collapse-" + section_id).children(".accordion-inner").find(".loaded").hide(); - - setTimeout(function(){ - $("loaded").find(".section-lock-notice").html(""); - $("loaded").find(".section-lock-notice").hide(); - $(".question-form").find("select").removeAttr('disabled'); - $(".question-div").find(".question-readonly").hide(); - $(".question-div").find(".question-form").show(); - - $("#collapse-" + section_id).children(".accordion-inner").find(".loading").hide(); - $("#collapse-" + section_id).children(".accordion-inner").find(".loaded").show(); - $('html, body').animate({ - 'scrollTop': $("#current_question").offset().top - },1000); - },8000); - } - - window.onbeforeunload = function(){ - var message = null; - if ($.fn.is_dirty()) { - var questions = $.fn.get_unsaved_questions(); - message = __('You have unsaved answers in the following sections:') - $.each(questions, function(section_text, question_texts){ - message += "\n\u2022"+section_text; - }); - return message; - } - }; - - //accordion guidance - $('.accordion-guidance-link').on('click', function (e) { - e.stopPropagation(); - var show = true; - var div_to_toggle = $($(this).attr("href")); - if (div_to_toggle.hasClass('in')) { - show = false; - } - $($(this).attr("href")).toggleClass("in"); - if (show) { - $(this).children(".plus-laranja").removeClass("plus-laranja").addClass("minus-laranja"); - } - else { - $(this).children(".minus-laranja").removeClass("minus-laranja").addClass("plus-laranja"); - } - delete show; - delete div_to_toggle; - e.preventDefault(); - }); - - - // Handle section actions on accordion expansion/collapse - $('.section-collapse').on('hide', function(){ - var section = $(this); - var section_id = section.attr("id").split('-')[1]; - if ($.fn.is_dirty(section_id)) { - $('#unsaved-answers-'+section_id).text(""); - $.each($.fn.get_unsaved_questions(section_id), function(index, question_text){ - $('#unsaved-answers-'+section_id).append("
  • "+question_text+"
  • "); - }); - $('#section-' + section_id + '-collapse-alert').modal(); - } - }); - +$(document).ready(function() { + /*---------------- + Popup button listeners for when answers are not saved + ------------------*/ $(".cancel-section-collapse").click(function () { var section_id = $(this).attr('data-section'); $("#collapse-" + section_id).collapse("show"); @@ -160,209 +18,35 @@ $("#collapse-" + section_id).find("input[type='submit']").click(); $('#section-' + section_id + '-collapse-alert').modal("hide"); }); - - // COMMENTS Javascript - - //action for show comment block on the right side of a question - $('.comments_accordion_button').click(function(e){ - var q_id = $(this).closest(".question_right_column_nav").find(".question_id").val(); - $(this).parent().addClass("active"); - $(this).closest(".question_right_column_ul").find(".guidance_tab_class").removeClass("active"); - $('#guidance-question-area-'+ q_id).hide(); - $('#comment-question-area-'+ q_id).show(); + /*---------------- + Listener for clicks in any of the right column of question tabs (e.g. Guidances, Notes) + ------------------*/ + $('.right_column_tab_link').click(function(e){ e.preventDefault(); + // Find current active tab and hide it + var active = $(this).closest('.question_right_column_ul').children().filter('.active'); + active.removeClass('active'); + $(this).closest('.question-area-right-column').find('div.'+active.attr('class')).hide(); + // Select the clicked tab as active and display its content + active = $(this).parent(); + $(this).closest('.question-area-right-column').find('div.'+active.attr('class')).show(); + active.addClass('active'); }); - - //action for show guidance block on the right side of a question - $('.guidance_accordion_button').click(function(e){ - var q_id = $(this).closest(".question_right_column_nav").find(".question_id").val(); - $(this).parent().addClass("active"); - $(this).closest(".question_right_column_ul").find(".comment_tab_class").removeClass("active"); - $('#comment-question-area-'+ q_id).hide(); - $('#guidance-question-area-'+ q_id).show(); + /*---------------- + Accordion toggling for displaying/hiding guidances. + TODO moving to lib/assets/javascripts/annotations when partials for guidances are created + ------------------*/ + $('.accordion-guidance-link').on('click', function (e) { + e.stopPropagation(); e.preventDefault(); + var accordion_body = $($(this).attr("href")); + accordion_body.toggleClass("in"); //adds or removes 'in' class from accordion_body + if(accordion_body.hasClass('in')){ //accordion expanded + $(this).children(".plus-laranja").removeClass("plus-laranja").addClass("minus-laranja"); //display minus + } + else { //accordion collapsed + $(this).children(".minus-laranja").removeClass("minus-laranja").addClass("plus-laranja"); //display plus + } }); }); -$.fn.get_unsaved_questions = function(section_id) { - if (section_id != null) { - var questions = new Array(); - $.each(dirty[section_id], function(question_id,value){ - if (value && question_id != 'undefined') { - questions.push($("label[for='answer-text-"+question_id+"']").text()); - } - }); - return questions; - } - else { - var questions = {}; - $.each(dirty, function(section_id,question_ids){ - var section_text = $("#section-header-"+section_id).clone().children().remove().end().text().trim(); - questions[section_text] = new Array(); - $.each(question_ids, function(question_id,value){ - if (value && question_id != 'undefined') { - questions[section_text].push($("label[for='answer-text-"+question_id+"']").text()); - } - }); - }); - return questions; - } -}; - -$.fn.is_dirty = function(section_id, question_id) { - if (section_id != null) { - if (dirty[section_id] != null) { - if (question_id != null) { - if (dirty[section_id][question_id] != null) { - return dirty[section_id][question_id]; - } - else { - return false; - } - } - else { - var is_dirty = false; - $.each(dirty[section_id], function(question_id, value){ - if (value && question_id != 'undefined') { - is_dirty = true; - } - }); - return is_dirty; - } - } - } - else { - var is_dirty = false; - $.each(dirty, function(section_id, questions){ - $.each(questions, function(question_id, value){ - if (value && question_id != 'undefined') { - is_dirty = true; - } - }); - }); - return is_dirty; - } - return false; -}; - - -$.fn.update_section_progress = function(data) { - s_id = $(this).attr("id").split('-')[0]; - s_qs = data.sections[s_id]["num_questions"]; - question_word = "questions" - if (s_qs == 1) { - question_word = "question"; - } - s_as = data.sections[s_id]["num_answers"]; - $(this).text("("+s_qs+" "+question_word+", "+s_as+" answered)"); - if (s_qs == s_as) { - $(this).removeClass("label-warning"); - $(this).addClass("label-info"); - } -}; - -$.fn.update_plan_progress = function(data) { - $("#questions-progress").css("width", (data.num_answers/data.num_questions*100)+"%"); - $("#questions-progress-title").text(data.num_answers+"/"+data.num_questions + " " + __('questions answered')); - $('#export-progress').css('width', data.space_used + '%'); - $("#export-progress-title").text(__('approx. %{space_used}% of available space used', {space_used: data.space_used})); - if (data.space_used >= 100) { - $('#export-progress').removeClass("space"); - $('#export-progress').addClass("full"); - $('#export-progress-title').addClass("bar-full-text"); - } - else { - $('#export-progress').removeClass("full"); - $('#export-progress').addClass("space"); - $('#export-progress-title').removeClass("bar-full-text"); - } -}; - -$.fn.update_question_timestamp = function(question_id) { - q_status = $('#'+question_id+'-status'); - var t = q_status.children("abbr:first"); - var timestamp = new Date(t.attr('data-time')); - if (timestamp != null) { - timestamp = new Date(Number(timestamp) * 1000); - q_status.text(""); - q_status.append( __('Answered') + " " + __(' by ') + data.questions[question_id]["answered_by"]); - t = q_status.children("abbr:first"); - // Update label to indicate successful submission - q_status.removeClass("label-info label-warning"); - q_status.addClass("label-success"); - // Set timestamp text and data - t.text(timestamp.toUTCString()); - //t.attr('title', timestamp.toISOString()).data("timeago",null).timeago(); - t.attr('data-time', timestamp.toISOString()); - return true; - } - return false; -}; - -$.fn.update_timestamp = function(question_id, data) { - q_status = $('#'+question_id+'-status'); - var t = q_status.children("abbr:first"); - var current_timestamp = new Date(t.attr('data-time')); - var timestamp = data.questions[question_id]["answer_updated_at"]; - if (timestamp != null) { - timestamp = new Date(Number(timestamp) * 1000); - if (timestamp.getTime() != current_timestamp.getTime()) { - q_status.text(""); - q_status.append( __('Answered') + " " + __(' by ') + data.questions[question_id]["answered_by"]); - t = q_status.children("abbr:first"); - // Update label to indicate successful submission - q_status.removeClass("label-info label-warning"); - q_status.addClass("label-success"); - // Set timestamp text and data - t.text(timestamp.toUTCString()); - //t.attr('title', timestamp.toISOString()).data("timeago",null).timeago(); - t.attr('data-time', timestamp.toISOString()); - return true; - } - } - return false; -}; - -// TODO: Should we drop this now that the locking check has been removed? -$.fn.check_section_lock = function() { - var section = $(this); - var section_id = section.attr("id").split('-')[1]; - $.getJSON("locked?section_id="+section_id, function(data) { - if (data.locked) { - section.find(".section-lock-notice").html("

    " + __('This section is locked for editing by ') + data.locked_by + ".

    "); - section.find(".section-lock-notice").show(); - section.find("input").attr('disabled', 'disabled'); - section.find(".question-form").hide(); - section.find("select").attr('disabled', 'disabled'); - section.find(".question-readonly").show(); - } - else { - // LIBDMP-137 - // Changed post request 'lock_section' to 'lock_section.json'. 'lock_section' unnecessary returns a huge html response and takes a quite lot of time to process(3sec) lowering server - // performance when there are large number of concurrent users. - $.post('lock_section', {section_id: section_id} ); - section.find(".section-lock-notice").html(""); - section.find(".section-lock-notice").hide(); - section.find("input").removeAttr('disabled'); - section.find(".question-form").show(); - section.find("select").removeAttr('disabled'); - section.find(".question-readonly").hide(); - } - }); - return true; -}; - -$.fn.toggle_dirty = function(question_id, is_dirty) { - console.log($(this)); - section_id = $(this).attr("id").split('-')[0]; - if (dirty[section_id] == null) { - dirty[section_id] = {}; - } - dirty[section_id][question_id] = is_dirty; - if (is_dirty) { - $("#"+question_id+"-unsaved").show(); - } - else { - $("#"+question_id+"-unsaved").hide(); - } -}; diff --git a/lib/assets/javascripts/plans/edit.js b/lib/assets/javascripts/plans/edit.js new file mode 100644 index 0000000..941f1a5 --- /dev/null +++ b/lib/assets/javascripts/plans/edit.js @@ -0,0 +1,10 @@ +$(document).ready(function(){ + /*---------------- + Listener for click on buttons containing show-edit-toggle class + ------------------*/ + $(".show-edit-toggle").click(function (e) { + e.preventDefault(); + $(".edit-plan-details").toggle(); + $(".show-plan-details").toggle(); + }); +}); \ No newline at end of file diff --git a/lib/assets/javascripts/plans/share.js b/lib/assets/javascripts/plans/share.js new file mode 100644 index 0000000..3ea4591 --- /dev/null +++ b/lib/assets/javascripts/plans/share.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + /*---------------- + Listener for changes in access-level for a plan shared with a user + TODO partial update instead of forcing a page reload + ------------------*/ + $(".toggle-access-level").change(function(){ + $(this).closest('form').submit(); + }); +}); \ No newline at end of file diff --git a/lib/assets/javascripts/projects.js b/lib/assets/javascripts/projects.js deleted file mode 100644 index c32016c..0000000 --- a/lib/assets/javascripts/projects.js +++ /dev/null @@ -1,111 +0,0 @@ -$( document ).ready(function() { - $(".select2-container").select2(); - - // The following function references a JSON array that is - // constructed in app/view/projects/_dropdown_new_project.html.erb - // ---------------------------------------------------------- - function getTemplates(){ - // decide whether to filter by funder templates or institution templates - // if the #other_funder_name is hidden, then do not include institutional templates - // by default use the funder's templates - var funder = [$("#plan_funder_id").val()]; - - var template = $("#project_dmptemplate_id :selected").val(); - - selectItemsFromJsonArray(templates, 'organisation', orgs, function(array){ - // Clear and reload the contents of the dropdown - $("#project_dmptemplate_id").html("").select2( {data: array} ).val(); - - // If there are less than 2 templates, hide the dropdown - if(array.length < 2){ - $("#template-control-group").hide(); - //reloadGuidanceOptions(); - - }else{ - // Select the first item in the list if there was none selected - if(template == undefined){ - $("#project_dmptemplate_id").val(array[0]['id']).trigger('change'); - }else{ - //reloadGuidanceOptions(); - } - - $("#template-control-group").show(); - - // if there is only one template disable the dropdown - if(array.length > 1){ - $("#project_dmptemplate_id").prop('disabled', false); - }else{ - $("#project_dmptemplate_id").prop('disabled', true); - } - } - }); - } - - // The following function references a JSON array that is - // constructed in app/view/projects/_dropdown_new_project.html.erb - // ---------------------------------------------------------- - function reloadGuidanceOptions() { - var institution = $("#project_institution_id").select2('val'); - var template = $("#project_dmptemplate_id :selected").val(); - var options = null; - - if(!template){ - template = $("#project_dmptemplate_id :selected").children().first().val(); - } - - options_container = $("#guidance-control-group"); - options_container = options_container.find(".choices-group"); - options_container.empty(); - - var orgs = [$("#project_funder_id").val(), - $("#project_institution_id").val()]; - - // select all of the guidance groups available to the funder and/or institution - selectItemsFromJsonArray(guidance_for_template_or_organisation, 'organisation', - institution, function(array){ - array = guidance_always_available.concat(array); - - for(var i = 0; i < array.length; i++){ - var selected = false - - options_container.append( - "
  • " + - "" + - "
  • " - ); - } - - if(array.length > 0){ - $("#guidance-control-group").show(); - }else{ - $("#guidance-control-group").hide(); - } - }); - } - - // ---------------------------------------------------------- - $("#project_is_test").click(function(e){ - if(this.checked){ - $("input[name='project[visibility]']").prop('disabled', true); - $(".is-test-label").show(); - }else{ - $("input[name='project[visibility]']").prop('disabled', false); - $(".is-test-label").hide(); - } - }); - - // Handle the 'test' flag on page load - // ---------------------------------------------------------- - if($("#project_is_test").checked){ - $("input[name='project[visibility]']").prop('disabled', true); - $(".is-test-label").show(); - }else{ - $("input[name='project[visibility]']").prop('disabled', false); - $(".is-test-label").hide(); - } - -}); diff --git a/lib/assets/javascripts/shared/register_form.js b/lib/assets/javascripts/shared/register_form.js index 82b077d..0a2be6c 100644 --- a/lib/assets/javascripts/shared/register_form.js +++ b/lib/assets/javascripts/shared/register_form.js @@ -4,7 +4,21 @@ var valid_password = false; var valid_password_confirmation = false; var valid_accept_terms = false; - + /*---------------- + Inits select2 for any typeahead class (e.g. at views/shared/_register_form.html.erb) + ------------------*/ + $('.typeahead').select2({ + width: "element", + allowClear: true + }); + // TODO removing once the new create account functionality is in place + $("#other-org-link > a").click(function(e){ + e.preventDefault(); + var other_org = $("#other-organisation-name").attr("data-orgs").split(","); + $("#user_organisation_id").select2("val", other_org); + $("#other-org-link").hide(); + $("#user_organisation_id").change(); + }); $("#user_email.text_field.reg-input").change(function(){ if (email_regex.test($(this).val())) { $(this).next().hide();