From 42d00845eae1d56eaa0493ab9bf4254184ee73d8 Mon Sep 17 00:00:00 2001 From: David M <207745043+davidmillen50@users.noreply.github.com> Date: Wed, 13 Aug 2025 17:56:05 +0100 Subject: [PATCH 1/2] Feat: add member not editing on members page Added a modal for admins to edit notes posted to a member's profile --- .../admin/member_notes_controller.rb | 24 ++++++++++ app/policies/member_note_policy.rb | 12 +++++ .../admin/member_notes/_member_note.html.haml | 17 ++++++- config/routes.rb | 2 +- .../admin/member_notes_controller_spec.rb | 47 +++++++++++++++++++ 5 files changed, 100 insertions(+), 2 deletions(-) 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..67c21b8c0 100644 --- a/app/policies/member_note_policy.rb +++ b/app/policies/member_note_policy.rb @@ -2,4 +2,16 @@ class MemberNotePolicy < ApplicationPolicy def create? user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) end + + def edit? + user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) + end + + def update? + user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) + end + + def destroy? + user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) + 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 From 489cc7e324c438f6edb55d482458785dfa72deb0 Mon Sep 17 00:00:00 2001 From: David M <207745043+davidmillen50@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:00:21 +0100 Subject: [PATCH 2/2] Fix: member note policy Ensure only admins can update and delete member notes --- app/policies/member_note_policy.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/policies/member_note_policy.rb b/app/policies/member_note_policy.rb index 67c21b8c0..208ec2509 100644 --- a/app/policies/member_note_policy.rb +++ b/app/policies/member_note_policy.rb @@ -3,15 +3,11 @@ def create? user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) end - def edit? - user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) - end - def update? - user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) + user&.has_role?(:admin) end def destroy? - user && (user.has_role?(:admin) || user.roles.where(resource_type: 'Chapter').any?) + user&.has_role?(:admin) end end