diff --git a/app/controllers/admin/member_notes_controller.rb b/app/controllers/admin/member_notes_controller.rb index 2f2e4f0b7..94fddbaa3 100644 --- a/app/controllers/admin/member_notes_controller.rb +++ b/app/controllers/admin/member_notes_controller.rb @@ -8,6 +8,30 @@ def create redirect_back fallback_location: root_path end + def update + @note = MemberNote.find(params[:id]) + authorize @note + + if @note.update(member_note_params) + flash[:notice] = 'Note updated successfully.' + else + flash[:error] = @note.errors.full_messages.to_sentence + end + + redirect_back fallback_location: root_path + end + + def destroy + @note = MemberNote.find(params[:id]) + authorize @note + if @note.destroy + flash[:notice] = 'Note deleted successfully.' + else + flash[:alert] = 'Failed to delete the note.' + end + redirect_back fallback_location: root_path + end + def member_note_params params.require(:member_note).permit(:note, :member_id) end diff --git a/app/policies/member_note_policy.rb b/app/policies/member_note_policy.rb index 7b8baa327..208ec2509 100644 --- a/app/policies/member_note_policy.rb +++ b/app/policies/member_note_policy.rb @@ -2,4 +2,12 @@ class MemberNotePolicy < ApplicationPolicy def create? user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) end + + def update? + user&.has_role?(:admin) + end + + def destroy? + user&.has_role?(:admin) + end end diff --git a/app/views/admin/member_notes/_member_note.html.haml b/app/views/admin/member_notes/_member_note.html.haml index 741db5844..019b26292 100644 --- a/app/views/admin/member_notes/_member_note.html.haml +++ b/app/views/admin/member_notes/_member_note.html.haml @@ -3,8 +3,23 @@ %span.fa-stack.text-primary %i.fas.fa-circle.fa-stack-2x %i.fas.fa-pencil-alt.fa-stack-1x.fa-inverse + .col-2.col-md-1 + = link_to 'Edit', "#edit-note-modal-#{action.id}", data: { bs_toggle: 'modal', bs_target: "#edit-note-modal-#{action.id}" } .col-9.col-md-11 %strong Note added by #{link_to(action.author.full_name, admin_member_path(action.author))} - %blockquote.blockquote.mb-0=action.note + %blockquote.blockquote.mb-0= action.note .date = l(action.created_at, format: :website_format) + + .modal.fade{ id: "edit-note-modal-#{action.id}", tabindex: "-1", role: "dialog" } + .modal-dialog + .modal-content + .modal-header + %h5.modal-title Edit Note for ID #{action.id} + %button.btn-close{ type: 'button', 'data-bs-dismiss': 'modal', 'aria-label': 'Close' } + .modal-body + = simple_form_for [:admin, member_note], html: { class: 'form-inline' } do |f| + = f.input :note, label: false, input_html: { rows: 3 } + = f.hidden_field :member_id, value: member_note.member_id + .text-right + = f.button :submit, 'Save note', class: 'btn btn-primary mb-0' diff --git a/config/routes.rb b/config/routes.rb index f5b29ccb0..51ca0a289 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -91,7 +91,7 @@ resources :bans, only: %i[index new create] end - resources :member_notes, only: [:create] + resources :member_notes, only: %i[create update destroy] resources :chapters, only: %i[index new create show edit update] do get :members diff --git a/spec/controllers/admin/member_notes_controller_spec.rb b/spec/controllers/admin/member_notes_controller_spec.rb index a839f2bb5..7bf2002f3 100644 --- a/spec/controllers/admin/member_notes_controller_spec.rb +++ b/spec/controllers/admin/member_notes_controller_spec.rb @@ -33,4 +33,51 @@ end.not_to change { MemberNote.all.count } end end + + describe 'PATCH #update' do + it "Doesn't allow anonymous users to update notes" do + patch :update, params: { id: member_note.id, member_note: { note: 'Updated note' } } + expect(response).to redirect_to(root_path) + end + + it "Doesn't allow regular users to update notes" do + login member + patch :update, params: { id: member_note.id, member_note: { note: 'Updated note' } } + expect(response).to redirect_to(root_path) + end + + it 'Allows chapter organisers to update notes' do + login admin + patch :update, params: { id: member_note.id, member_note: { note: 'Updated note' } } + expect(response).to redirect_to(root_path) + expect(flash[:notice]).to eq('Note updated successfully.') + end + + it "Doesn't allow blank notes to be updated" do + login admin + patch :update, params: { id: member_note.id, member_note: { note: ' ' } } + expect(response).to redirect_to(root_path) + expect(flash[:error]).to eq("Note can't be blank") + end + end + + describe 'DELETE #destroy' do + it "Doesn't allow anonymous users to delete notes" do + delete :destroy, params: { id: member_note.id } + expect(response).to redirect_to(root_path) + end + + it "Doesn't allow regular users to delete notes" do + login member + delete :destroy, params: { id: member_note.id } + expect(response).to redirect_to(root_path) + end + + it 'Allows chapter organisers to delete notes' do + login admin + delete :destroy, params: { id: member_note.id } + expect(response).to redirect_to(root_path) + expect(flash[:notice]).to eq('Note deleted successfully.') + end + end end