Skip to content

Commit

Permalink
edit user on partner #3308
Browse files Browse the repository at this point in the history
  • Loading branch information
numew committed Jan 17, 2025
1 parent ddf263d commit 1b5515e
Show file tree
Hide file tree
Showing 19 changed files with 382 additions and 366 deletions.
176 changes: 73 additions & 103 deletions assets/scripts/vanilla/controllers/back_partner_view/form_partner.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ function histoUpdateFieldsVisibility () {
function histoUpdateValueFromData (elementName, elementData, target) {
document.querySelector(elementName).value = target.getAttribute(elementData)
}
function histoUpdatePermissionsFromRole (editOrCreate, toggleValue) {

//TODO : remove editOrCreate param after feature_multi_territories deletion (will always be 'partner')
function histoUpdatePermissionsFromRole (editOrCreate) {
const elementTogglePermissionAffectation = document.querySelector('#user_' + editOrCreate + '_permission_affectation_toggle input')
const elementTextPermissionAffectation = document.querySelector('#user_' + editOrCreate + '_permission_affectation_text')
if (!elementTogglePermissionAffectation || !elementTextPermissionAffectation) {
Expand All @@ -68,12 +70,6 @@ function histoUpdatePermissionsFromRole (editOrCreate, toggleValue) {
elementTextPermissionAffectation.classList.remove('fr-hidden')
} else {
elementTogglePermissionAffectation.removeAttribute('disabled')
if (toggleValue === false && elementTogglePermissionAffectation.checked) {
elementTogglePermissionAffectation.click()
}
if (editOrCreate === 'edit' && toggleValue === true && !elementTogglePermissionAffectation.checked) {
elementTogglePermissionAffectation.click()
}
elementTextPermissionAffectation.classList.add('fr-hidden')
}
}
Expand Down Expand Up @@ -116,61 +112,6 @@ document.querySelectorAll('.btn-delete-partner').forEach(swbtn => {
})
})
})
let userEditedId = null

function clearErrors () {
const divErrorElements = document.querySelectorAll('.fr-input-group--error')
divErrorElements.forEach((divErrorElement) => {
divErrorElement.classList.remove('fr-input-group--error')
const pErrorElement = divErrorElement.querySelector('.fr-error-text')
if (pErrorElement) {
pErrorElement.classList.add('fr-hidden')
}
})
}
document.querySelectorAll('.btn-edit-partner-user').forEach(swbtn => {
swbtn.addEventListener('click', evt => {
clearErrors()
const target = evt.target
document.querySelectorAll('.fr-modal-user-edit_useremail').forEach(userItem => {
userItem.textContent = target.getAttribute('data-useremail')
})
userEditedId = target.getAttribute('data-userid')
if (target.getAttribute('data-submit-url')) {
document.querySelector('#fr-modal-user-edit form').action = target.getAttribute('data-submit-url')
}
histoUpdateValueFromData('#user_edit_userid', 'data-userid', target)
histoUpdateValueFromData('#user_edit_email', 'data-useremail', target)
histoUpdateValueFromData('#user_edit_nom', 'data-usernom', target)
histoUpdateValueFromData('#user_edit_prenom', 'data-userprenom', target)
const isMailingActive = target.getAttribute('data-userismailingactive')
if (isMailingActive === '1') {
document.querySelector('#user_edit_is_mailing_active-1').checked = true
} else {
document.querySelector('#user_edit_is_mailing_active-2').checked = true
}

const elementPermissionAffectation = document.querySelector('#user_edit_permission_affectation')
if (elementPermissionAffectation) {
elementPermissionAffectation.removeAttribute('disabled')
}

const userRole = target.getAttribute('data-userrole')
const rolesSelect = document.querySelector('#user_edit_roles')
rolesSelect.value = userRole
histoUpdatePermissionsFromRole('edit', target.getAttribute('data-userpermissionaffectation') === '1')

document.querySelector('#user_edit_form').addEventListener('submit', (e) => {
histoUpdateSubmitButton('#user_edit_form_submit', 'Edition en cours...')
})
})
})
if (document.querySelector('.fr-btn-add-user')) {
document.querySelector('.fr-btn-add-user').addEventListener('click', () => {
clearErrors()
userEditedId = null
})
}

if (document.querySelector('#partner_type')) {
histoUpdateFieldsVisibility()
Expand All @@ -179,19 +120,6 @@ if (document.querySelector('#partner_type')) {
})
}

if (document.querySelector('#user_create_roles')) {
document.querySelector('#user_create_roles').addEventListener('change', () => {
histoUpdatePermissionsFromRole('create', null)
})
histoUpdatePermissionsFromRole('create', null)
}
if (document.querySelector('#user_edit_roles')) {
document.querySelector('#user_edit_roles').addEventListener('change', () => {
histoUpdatePermissionsFromRole('edit', null)
})
histoUpdatePermissionsFromRole('edit', null)
}

const territorySelect = document.querySelector("#partner_territory");

if (territorySelect) {
Expand Down Expand Up @@ -240,10 +168,33 @@ deletePartnerForm.forEach(form => {
})

//TODO : delete with feature_multi_territories deletion
function clearErrors () {
const divErrorElements = document.querySelectorAll('.fr-input-group--error')
divErrorElements.forEach((divErrorElement) => {
divErrorElement.classList.remove('fr-input-group--error')
const pErrorElement = divErrorElement.querySelector('.fr-error-text')
if (pErrorElement) {
pErrorElement.classList.add('fr-hidden')
}
})
}

if (document.querySelector('.fr-btn-add-user')) {
document.querySelector('.fr-btn-add-user').addEventListener('click', () => {
clearErrors()
})
}

if (document.querySelector('#user_create_roles')) {
document.querySelector('#user_create_roles').addEventListener('change', () => {
histoUpdatePermissionsFromRole('create')
})
histoUpdatePermissionsFromRole('create')
}

const checkUserMail = (el) => {
const formData = new FormData()
formData.append('email', el.value)
formData.append('userEditedId', userEditedId)
formData.append('_token', el.getAttribute('data-token'))
fetch('/bo/partenaires/checkmail', {
method: 'POST',
Expand Down Expand Up @@ -281,7 +232,7 @@ emailInputs.forEach(emailInput => {
checkUserMail(this)
})
})
//END TODO
//END TODO : delete with feature_multi_territories deletion

loadWindowWithLocalStorage('click', '[data-filter-list-partner]', 'search-partner-form')
updateLocalStorageOnEvent('input', '#partner-input', 'back_link_partners')
Expand All @@ -290,48 +241,67 @@ updateLocalStorageOnEvent('change', '#partner-filters-types', 'back_link_partner
updateLocalStorageWithPaginationParams('click', '#partner-pagination a', 'back_link_partners')

//add for multi territories
document.querySelectorAll('.btn-edit-partner-user').forEach(swbtn => {
swbtn.addEventListener('click', event => {
const refreshUrl = event.target.dataset.refreshUrl;
document.querySelector('#fr-modal-user-edit button[type="submit"]').disabled = true;
document.querySelector('#fr-modal-user-edit-title').innerHTML = 'Chargement en cours...'
document.querySelector('#fr-modal-user-edit-form-container').innerHTML = 'Chargement en cours...'
fetch(refreshUrl).then(response => {
updateModaleFromResponse(response, '#fr-modal-user-edit', addEventListenerOnRoleChange)
})
})
})

const modalPartnerUserCreate = document?.querySelector('#fr-modal-user-create')
const btnSubmit = modalPartnerUserCreate?.querySelector('button[type="submit"]')
if(modalPartnerUserCreate){
modalPartnerUserCreate.addEventListener('dsfr.conceal', (event) => {
const refreshUrl = event.target.dataset.refreshUrl;
btnSubmit.disabled = true
modalPartnerUserCreate.querySelector('button[type="submit"]').disabled = true;
fetch(refreshUrl).then(response => {
managePartnerAddUserFormResponse(response)
updateModaleFromResponse(response, '#fr-modal-user-create', addEventListenerOnRoleChange)
})
})
}

function attachSubmitPartnerAddUserForm () {
document.querySelector('#partner-add-user-form').addEventListener('submit', (e) => {
e.preventDefault()
btnSubmit.disabled = true
const formData = new FormData(e.target)
fetch(e.target.action, {method: 'POST', body: formData}).then(response => {
managePartnerAddUserFormResponse(response)
function addEventListenerOnRoleChange(){
if (document.querySelector('#user_partner_role')) {
document.querySelector('#user_partner_role').addEventListener('change', () => {
histoUpdatePermissionsFromRole('partner')
})
})
histoUpdatePermissionsFromRole('partner')
}
}

function managePartnerAddUserFormResponse(response) {
console.log(response);
if (response.redirected) {
window.location.href = response.url
}else if (response.ok) {
function updateModaleFromResponse(response, modalSelector, callback = null){
if (response.ok) {
response.json().then((response) => {
document.querySelector('#partner-add-user-title').innerHTML = response.title
document.querySelector('#partner-add-user-form-container').innerHTML = response.content
attachSubmitPartnerAddUserForm()
if (document.querySelector('#user_partner_role')) {
document.querySelector('#user_partner_role').addEventListener('change', () => {
histoUpdatePermissionsFromRole('partner', null)
})
histoUpdatePermissionsFromRole('partner', null)
if (response.redirect) {
window.location.href = response.url
window.location.reload()
}else{
document.querySelector(modalSelector + '-title').innerHTML = response.title
document.querySelector(modalSelector + '-form-container').innerHTML = response.content
attachSubmitFormModal(modalSelector, callback)
if (typeof callback === 'function') {
callback();
}
btnSubmit.disabled = false
document.querySelector(modalSelector +' button[type="submit"]').disabled = false
}
})
}else{
const content = '<div class="fr-alert fr-alert--error" role="alert"><p class="fr-alert__title">Erreur</p><p>Une erreur est survenue veuillez fermer cette fenêtre.</p></div>'
document.querySelector('#partner-add-user-form-container').innerHTML = content
document.querySelector(modalSelector + '-form-container').innerHTML = content
}
}

function attachSubmitFormModal (modalSelector, callback) {
document.querySelector(modalSelector + ' form').addEventListener('submit', (e) => {
e.preventDefault()
document.querySelector(modalSelector + ' button[type="submit"]').disabled = true
const formData = new FormData(e.target)
fetch(e.target.action, {method: 'POST', body: formData}).then(response => {
updateModaleFromResponse(response, modalSelector, callback)
})
})
}
108 changes: 29 additions & 79 deletions src/Controller/Back/PartnerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Entity\User;
use App\Entity\UserPartner;
use App\Factory\UserFactory;
use App\Form\EditUserPartnerType;
use App\Form\PartnerPerimetreType;
use App\Form\PartnerType;
use App\Form\SearchPartnerType;
Expand Down Expand Up @@ -43,6 +44,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
Expand Down Expand Up @@ -378,7 +380,9 @@ public function addUserPartnerMulti(
$message = 'L\'utilisateur a bien été créé. Un e-mail de confirmation a été envoyé à '.$user->getEmail();
$this->addFlash('success', $message);

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents']);
$url = $this->generateUrl('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], UrlGeneratorInterface::ABSOLUTE_URL);

return $this->json(['redirect' => true, 'url' => $url]);
}
$formMultiMail->get('email')->addError(new FormError('Agent introuvalbe avec cette adresse e-mail.'));
}
Expand Down Expand Up @@ -422,7 +426,9 @@ public function addUserPartner(
$message = 'L\'utilisateur a bien été créé. Un e-mail de confirmation a été envoyé à '.$user->getEmail();
$this->addFlash('success', $message);

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents']);
$url = $this->generateUrl('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], UrlGeneratorInterface::ABSOLUTE_URL);

return $this->json(['redirect' => true, 'url' => $url]);
}
$content = $this->renderView('_partials/_modal_user_create_form.html.twig', ['formUserPartner' => $formUserPartner]);

Expand Down Expand Up @@ -496,94 +502,38 @@ public function addUser(
return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
}

#[Route('/{id}/editerutilisateur', name: 'back_partner_user_edit', methods: ['POST'])]
#[Route('/{partner}/editerutilisateur/{user}', name: 'back_partner_user_edit')]
public function editUser(
Request $request,
Partner $partner,
User $user,
Request $request,
UserManager $userManager,
UserRepository $userRepository,
PartnerRepository $partnerRepository,
ValidatorInterface $validator,
): Response {
$userId = $request->request->get('user_id');
$user = $userManager->find((int) $userId);
/** @var User $user */
if (!$userId || !$user || !$user->hasPartner($partner)) {
$this->addFlash('error', 'Utilisateur introuvable.');

return $this->redirectToRoute('back_partner_index', [], Response::HTTP_SEE_OTHER);
}
if (!$this->isCsrfTokenValid('partner_user_edit', $request->request->get('_token'))) {
$this->addFlash('error', 'Token CSRF invalide, merci d\'actualiser la page et réessayer.');

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
}
): JsonResponse|RedirectResponse {
$this->denyAccessUnlessGranted('USER_EDIT', $user);

$data = $request->get('user_edit');
if (!EmailFormatValidator::validate($data['email'])) {
$this->addFlash('error', 'L\'adresse e-mail n\'est pas valide.');

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
}
if ($data['email'] != $user->getEmail()) {
$userExist = $userRepository->findOneBy(['email' => $data['email']]);
if ($userExist && !\in_array('ROLE_USAGER', $userExist->getRoles())) {
$this->addFlash('error', 'Un utilisateur existe déjà avec cette adresse e-mail.');

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
}
$partnerExist = $partnerRepository->findOneBy(['email' => $data['email']]);
if ($partnerExist) {
$this->addFlash('error', 'Un partenaire existe déjà avec cette adresse e-mail.');

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
$originalEmail = $user->getEmail();
$editUserRoute = $this->generateUrl('back_partner_user_edit', ['partner' => $partner->getId(), 'user' => $user->getId(), 'from' => $request->query->get('from')]);
$formUserPartner = $this->createForm(EditUserPartnerType::class, $user, ['action' => $editUserRoute]);
$formUserPartner->handleRequest($request);
if ($formUserPartner->isSubmitted() && $formUserPartner->isValid()) {
if ($originalEmail != $user->getEmail()) {
$user->setPassword('');
$userManager->sendAccountActivationNotification($user);
}
}
if ($data['roles'] != $user->getRoles()[0]) {
if (!$this->canAttributeRole($data['roles'])) {
return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
$userManager->flush();
$this->addFlash('success', 'L\'utilisateur a bien été modifié.');
$url = $this->generateUrl('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], UrlGeneratorInterface::ABSOLUTE_URL);
if ('users' == $request->query->get('from')) {
$url = $this->generateUrl('back_user_index', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
}

$updateData = [
'nom' => $data['nom'],
'prenom' => $data['prenom'],
'roles' => $data['roles'],
'email' => $data['email'],
'isMailingActive' => $data['isMailingActive'],
'hasPermissionAffectation' => $data['hasPermissionAffectation'] ?? false,
];
if (!$this->isGranted(PartnerVoter::ASSIGN_PERMISSION_AFFECTATION, $partner)) {
unset($updateData['hasPermissionAffectation']);
} else {
$updateData['hasPermissionAffectation'] = $updateData['hasPermissionAffectation'] ?? false;
return $this->json(['redirect' => true, 'url' => $url]);
}
$content = $this->renderView('_partials/_modal_user_edit_form.html.twig', ['formUserPartner' => $formUserPartner]);

$user = $userManager->updateUserFromData(
user: $user,
data: $updateData,
save: false
);

$errors = $validator->validate($user);
foreach ($errors as $error) {
$this->addFlash('error', $error->getMessage());
}
if (0 === \count($errors)) {
$userManager->save($user);
$message = 'L\'utilisateur a bien été modifié.';
$this->addFlash('success', $message);
}

$redirect_to = $request->request->get('redirect_to');
if ('userList' === $redirect_to) {
return $this->redirectToRoute('back_user_index', [], Response::HTTP_SEE_OTHER);
}

return $this->redirectToRoute('back_partner_view', ['id' => $partner->getId(), '_fragment' => 'agents'], Response::HTTP_SEE_OTHER);
return $this->json(['content' => $content, 'title' => 'Modifier le compte de : '.$user->getEmail()]);
}

// TODO : delete with feature_multi_territories deletion
private function canAttributeRole(string $role): bool
{
if (empty($role)) {
Expand Down
Loading

0 comments on commit 1b5515e

Please sign in to comment.