Merge pull request #8728 from demarches-simplifiees/revoke-usager-transfert-demande

[usager] peut révoquer une demande de transfert
This commit is contained in:
Lisa Durand 2023-03-10 09:21:59 +00:00 committed by GitHub
commit 1f03130d52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 157 additions and 71 deletions

View file

@ -157,6 +157,10 @@
word-wrap: normal !important;
}
.ml-auto {
margin-left: auto;
}
// generate spacer utility like bootstrap my-2 -> margin-left/right: 2 * $default-spacer
// using $direction.key as css modifier, $direction.values to set css properties
// scale it using $steps

View file

@ -8,10 +8,6 @@
padding: (2 * $default-spacer) $default-spacer;
}
td {
padding: 0;
}
a {
background-image: none; // remove DSFR underline
}
@ -78,6 +74,10 @@
margin-bottom: 0;
}
}
.no-border {
background-image: none;
}
}
.file-hidden-by-user {
@ -87,3 +87,7 @@
background-color: rgba(242, 137, 0, 0.6) !important;
}
}
table.display-table {
display: table;
}

View file

@ -19,9 +19,15 @@ module Users
end
def destroy
transfer = DossierTransfer.find_by!(id: params[:id], email: current_user.email)
transfer = DossierTransfer.find(params[:id])
authorized = (transfer.email == current_user.email || transfer.dossiers.exists?(dossiers: { user: current_user }))
transfer.destroy_and_nullify
if authorized
transfer.destroy_and_nullify
flash.notice = t("users.dossiers.transferer.destroy")
else
flash.alert = t("users.dossiers.transferer.unauthorized_destroy")
end
redirect_to dossiers_path
end

View file

@ -7,7 +7,7 @@
- if has_actions
= render Dropdown::MenuComponent.new(wrapper: :div, wrapper_options: {class: 'invite-user-actions'}, menu_options: {id: dom_id(dossier, :actions_menu)}, button_options: {class: 'fr-btn--sm fr-btn--secondary'}) do |menu|
= render Dropdown::MenuComponent.new(wrapper: :div, wrapper_options: {class: 'invite-user-actions'}, menu_options: {id: dom_id(dossier, :actions_menu)}, button_options: {class: 'fr-btn--sm'}) do |menu|
- menu.with_button_inner_html do
= t('views.users.dossiers.dossier_action.actions')

View file

@ -1,36 +1,47 @@
- if dossiers.present?
%table.table.dossiers-table.hoverable
%caption= t('views.users.dossiers.dossiers_list.caption')
%thead
%tr
%th.number-col{ scope: :col }= t('views.users.dossiers.dossiers_list.n_dossier')
%th{ scope: :col }= t('views.users.dossiers.dossiers_list.procedure')
- if dossiers.present?
%th{ scope: :col }= t('views.users.dossiers.dossiers_list.requester')
%th.status-col{ scope: :col }= t('views.users.dossiers.dossiers_list.status')
%th.updated-at-col{ scope: :col }= t('views.users.dossiers.dossiers_list.updated')
%th.sr-only{ scope: :col }= t('views.users.dossiers.dossiers_list.actions')
%tbody
- dossiers.each do |dossier|
%tr{ data: { 'dossier-id': dossier.id } }
%th.number-col{ scope: :row }
= link_to(url_for_dossier(dossier), class: 'cell-link', tabindex: -1) do
%span.icon.folder
= dossier.id
%td
= link_to(url_for_dossier(dossier), class: 'cell-link') do
= procedure_libelle(dossier.procedure)
.fr-table.fr-table--bordered
%table.table.dossiers-table.hoverable
%caption= t('views.users.dossiers.dossiers_list.caption')
%thead
%tr
%th.number-col{ scope: :col }= t('views.users.dossiers.dossiers_list.n_dossier')
%th{ scope: :col }= t('views.users.dossiers.dossiers_list.procedure')
- if dossiers.present?
%td
%span.cell-link= demandeur_dossier(dossier)
%td.status-col
= status_badge(dossier.state)
%td.updated-at-col.cell-link
= try_format_date(dossier.updated_at)
%td.action-col
= render partial: 'dossier_actions', locals: { dossier: dossier }
%th{ scope: :col }= t('views.users.dossiers.dossiers_list.requester')
%th.status-col{ scope: :col }= t('views.users.dossiers.dossiers_list.status')
%th.updated-at-col{ scope: :col }= t('views.users.dossiers.dossiers_list.updated')
%th.action-col.follow-col{ scope: :col }= t('views.users.dossiers.dossiers_list.actions')
%tbody
- dossiers.each do |dossier|
- if dossier.transfer.present?
%tr.fr-background-alt--blue-france.no-border
%td.fr-py-2w{ colspan: 100 }
.flex.align-center
%p.fr-mb-0
%small
= t('views.users.dossiers.transfers.sender_demande_en_cours', id: dossier.id, email: dossier.transfer.email)
.ml-auto
= link_to t('views.users.dossiers.transfers.revoke'), transfer_path(dossier.transfer), class: 'fr-btn fr-btn--sm fr-btn--tertiary-no-outline', method: :delete
= paginate(dossiers)
%tr{ data: { 'dossier-id': dossier.id } }
%th.number-col{ scope: :row }
= link_to(url_for_dossier(dossier), class: 'cell-link', tabindex: -1) do
%span.icon.folder
= dossier.id
%td
= link_to(url_for_dossier(dossier), class: 'cell-link') do
= procedure_libelle(dossier.procedure)
- if dossiers.present?
%td
%span.cell-link= demandeur_dossier(dossier)
%td.status-col
= status_badge(dossier.state)
%td.updated-at-col.cell-link
= try_format_date(dossier.updated_at)
%td.action-col.follow-col
= render partial: 'dossier_actions', locals: { dossier: dossier }
= paginate(dossiers)
- else
.blank-tab

View file

@ -1,31 +1,34 @@
- if dossier_transfers.present?
%ul.dossiers-transfers.mb-2
- dossier_transfers.each do |transfer|
%li.mb-4
.transfer-details.mb-2
Demande de transfert Nº #{transfer.id} envoyé par #{transfer.dossiers.first.user.email}
%table.table.dossiers-table.hoverable
%thead
%tr
%th.number-col= t('views.users.dossiers.dossiers_list.n_dossier')
%th= t('views.users.dossiers.dossiers_list.procedure')
%th= t('views.users.dossiers.dossiers_list.status')
%th Date de dépot
%tbody
- transfer.dossiers.each do |dossier|
%tr{ data: { 'transfer-id': transfer.id } }
%td.number-col
%span.icon.folder
= dossier.id
%td= dossier.procedure.libelle
%td= status_badge(dossier.state)
%td{ style: 'padding: 18px;' }= (dossier.depose_at || dossier.created_at).strftime('%d/%m/%Y')
.fr-table.fr-table--bordered
%table.table.dossiers-table.display-table
%thead
%tr
%th.number-col= t('views.users.dossiers.dossiers_list.n_dossier')
%th= t('views.users.dossiers.dossiers_list.procedure')
%th= t('views.users.dossiers.dossiers_list.status')
%th.action-col.follow-col Date de dépot
%tbody
- dossier_transfers.each do |transfer|
- transfer.dossiers.each do |dossier|
%tr.fr-background-alt--blue-france.no-border
%td.fr-py-2w{ colspan: 100 }
.flex.align-center
%p.fr-mb-0
%small
= t('views.users.dossiers.transfers.receiver_demande_en_cours', id: dossier.id, email: transfer.dossiers.first.user.email)
.ml-auto
= link_to t('views.users.dossiers.transfers.accept'), transfer_path(transfer), class: "fr-btn fr-btn--sm fr-btn--tertiary", method: :put
.transfer-actions.mt-4
= link_to "Accepter", transfer_path(transfer), class: "button primary", method: :put
= link_to "Rejeter", transfer_path(transfer), class: "button danger", method: :delete
= link_to t('views.users.dossiers.transfers.reject'), transfer_path(transfer), class: "fr-btn fr-btn--sm fr-btn--tertiary-no-outline", method: :delete
%tr{ data: { 'transfer-id': transfer.id } }
%th.number-col{ scope: :row }
%span.icon.folder
= dossier.id
%td= dossier.procedure.libelle
%td= status_badge(dossier.state)
%td.action-col.follow-col{ style: 'padding: 18px;' }= (dossier.depose_at || dossier.created_at).strftime('%d/%m/%Y')
= paginate(dossier_transfers)
= paginate(dossier_transfers)
- else
.blank-tab

View file

@ -357,6 +357,12 @@ en:
status: "Status"
updated: "Updated"
actions: "Actions"
transfers:
sender_demande_en_cours: "A transfer request is pending on file Nº %{id} to %{email}"
receiver_demande_en_cours: "Transfer request on file Nº %{id} sent by %{email}"
revoke: Revoke this request
accept: Accept
reject: Reject
dossier_action:
edit_dossier: "Edit the file"
start_other_dossier: "Start another empty file"

View file

@ -361,6 +361,12 @@ fr:
transfer_dossier: "Transférer le dossier"
edit_draft: "Modifier le brouillon"
actions: "Actions"
transfers:
sender_demande_en_cours: "Une demande de transfert est en cours sur le dossier Nº %{id} pour %{email}"
receiver_demande_en_cours: "Demande de transfert pour le dossier Nº %{id} envoyé par %{email}"
revoke: Révoquer cette demande
accept: Accepter
reject: Rejeter
sessions:
new:
sign_in: Connexion à %{application_name}

View file

@ -9,3 +9,5 @@ en:
email_label: Email of the recipient account
submit: Send transfer request
notice_sent: The transfer request has been sent successfully
destroy: The transfer request has been deleted successfully
unauthorized_destroy: You don't have the authorization to delete this transfer request

View file

@ -9,3 +9,5 @@ fr:
email_label: Email du compte destinataire
submit: Envoyer la demande de transfert
notice_sent: L'invitation au transfert a été envoyée avec succès
destroy: La demande de transfert a été supprimée avec succès
unauthorized_destroy: Vous n'avez pas l'autorisation pour supprimer cette demande de transfert

View file

@ -4,19 +4,61 @@ describe Users::TransfersController, type: :controller do
let(:dossier) { create(:dossier, user: sender_user) }
describe 'DELETE destroy' do
let(:dossier_transfert) { DossierTransfer.initiate(recipient_user.email, [dossier]) }
context "as transfer receiver" do
let(:dossier_transfert) { DossierTransfer.initiate(recipient_user.email, [dossier]) }
subject { delete :destroy, params: { id: dossier_transfert.id } }
subject { delete :destroy, params: { id: dossier_transfert.id } }
before do
sign_in(recipient_user)
before do
sign_in(recipient_user)
end
it { expect { subject }.not_to raise_error }
it "deletes dossier transfert" do
subject
expect { dossier_transfert.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { (flash.notice).to eq('La demande de transfert a été supprimée avec succès') }
expect { (subject).to redirect_to dossiers_path }
end
end
it { expect { subject }.not_to raise_error }
context "as transfer sender" do
let(:dossier_transfert) { DossierTransfer.initiate(recipient_user.email, [dossier]) }
it "deletes dossier transfert" do
subject
expect { dossier_transfert.reload }.to raise_error(ActiveRecord::RecordNotFound)
subject { delete :destroy, params: { id: dossier_transfert.id } }
before do
sign_in(sender_user)
end
it { expect { subject }.not_to raise_error }
it "deletes dossier transfert" do
subject
expect { dossier_transfert.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context "as transfer unauthorized" do
let(:dossier_transfert) { DossierTransfer.initiate(recipient_user.email, [dossier]) }
let(:random_user) { create(:user) }
subject { delete :destroy, params: { id: dossier_transfert.id } }
before do
sign_in(random_user)
end
it { expect { subject }.not_to raise_error }
it "does not delete dossier transfert" do
subject
expect { dossier_transfert.reload.to eq(dossier_transfert) }
expect { (flash.alert).to eq("Vous n'avez pas l'autorisation pour supprimer cette demande de transfert") }
expect { (subject).to redirect_to dossiers_path }
end
end
end

View file

@ -25,7 +25,7 @@ describe 'Transfer dossier:' do
login_as other_user, scope: :user
visit dossiers_path
expect(page).to have_content("Demande de transfert #{dossier.reload.transfer.id} envoyé par #{user.email}")
expect(page).to have_content("Demande de transfert pour le dossier #{dossier.id} envoyé par #{user.email}")
click_on 'Accepter'
expect(page).to have_current_path(dossiers_path)
end