@@ -7,6 +7,7 @@ use App\Entity\Ticket\TicketMessage; | |||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore; | |||
@@ -28,18 +29,23 @@ use EasyCorp\Bundle\EasyAdminBundle\Security\Permission; | |||
use Lc\SovBundle\Factory\Ticket\TicketFactory; | |||
use Lc\SovBundle\Field\StatusField; | |||
use Lc\SovBundle\Form\Ticket\TicketFormType; | |||
use Lc\SovBundle\Form\Ticket\TicketStatusType; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Controller\AbstractAdminController; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use Symfony\Component\HttpFoundation\Request; | |||
use Symfony\Component\HttpFoundation\Response; | |||
use Symfony\Component\Translation\TranslatableMessage; | |||
class TicketAdminController extends AbstractAdminController | |||
{ | |||
protected $ticketFactory; | |||
protected $adminUrlGenerator; | |||
public function __construct(TicketFactory $ticketFactory) | |||
public function __construct(TicketFactory $ticketFactory, AdminUrlGenerator $adminUrlGenerator) | |||
{ | |||
$this->ticketFactory = $ticketFactory; | |||
$this->adminUrlGenerator = $adminUrlGenerator; | |||
} | |||
public static function getEntityFqcn(): string | |||
@@ -47,6 +53,16 @@ class TicketAdminController extends AbstractAdminController | |||
return TicketInterface::class; | |||
} | |||
public function configureAssets(Assets $assets): Assets | |||
{ | |||
$assets = parent::configureAssets($assets); | |||
$assets->addWebpackEncoreEntry('adminlte-ticket'); | |||
return $assets; | |||
} | |||
public function configureFields(string $pageName): iterable | |||
{ | |||
return [ | |||
@@ -88,14 +104,6 @@ class TicketAdminController extends AbstractAdminController | |||
]; | |||
} | |||
public function configureCrud(Crud $crud): Crud | |||
{ | |||
$crud | |||
->overrideTemplate('crud/detail', '@LcSov/admin/ticket/detail.html.twig'); | |||
return parent::configureCrud($crud); | |||
} | |||
public function configureActions(Actions $actions): Actions | |||
{ | |||
$actions | |||
@@ -113,7 +121,7 @@ class TicketAdminController extends AbstractAdminController | |||
if ($form->isSubmitted() && $form->isValid()) { | |||
$ticket = $form->getData(); | |||
foreach($ticket->getTicketMessages() as $ticketMessage){ | |||
foreach ($ticket->getTicketMessages() as $ticketMessage) { | |||
$this->get('em')->persist($ticketMessage); | |||
} | |||
@@ -130,4 +138,50 @@ class TicketAdminController extends AbstractAdminController | |||
] | |||
); | |||
} | |||
public function detail(AdminContext $context) | |||
{ | |||
$ticket = $context->getEntity()->getInstance(); | |||
$url = $this->adminUrlGenerator | |||
->setAction('ticketStatusAction') | |||
->generateUrl(); | |||
$formTicketStatus = $this->createForm( | |||
TicketStatusType::class, | |||
$ticket, | |||
[ | |||
'action' => $url, | |||
'method' => 'POST', | |||
] | |||
); | |||
return $this->render( | |||
'@LcSov/admin/ticket/detail.html.twig', | |||
[ | |||
'form_ticket_status' => $formTicketStatus->createView(), | |||
'ticket' => $ticket, | |||
] | |||
); | |||
} | |||
public function ticketStatusAction() | |||
{ | |||
$request = $this->get('request')->getMainRequest(); | |||
$ticket = $request->attributes->get('easyadmin_context')->getEntity()->getInstance(); | |||
$formTicketStatusForm = $this->createForm(TicketStatusType::class, $ticket); | |||
$formTicketStatusForm->handleRequest($request); | |||
$success = false; | |||
if ($formTicketStatusForm->isSubmitted() && $formTicketStatusForm->isValid()) { | |||
$this->get('em')->persist($ticket); | |||
$this->get('em')->flush(); | |||
$success = true; | |||
} | |||
return new JsonResponse(['success' => $success]); | |||
} | |||
} |
@@ -2,7 +2,6 @@ | |||
namespace Lc\SovBundle\Form\Ticket; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketModel; | |||
@@ -19,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class TicketFormType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $translatorAdmin; | |||
@@ -3,6 +3,7 @@ | |||
namespace Lc\SovBundle\Form\Ticket; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
@@ -13,11 +14,13 @@ use Lc\SovBundle\Model\Ticket\TicketModel; | |||
class TicketStatusType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $translatorAdmin; | |||
public function __construct(EntityManagerInterface $em) | |||
public function __construct(EntityManagerInterface $em, TranslatorAdmin $translatorAdmin) | |||
{ | |||
$this->em = $em; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
@@ -25,15 +28,12 @@ class TicketStatusType extends AbstractType | |||
$builder->add( | |||
'status', | |||
ChoiceType::class, | |||
array( | |||
'choices' => array( | |||
'field.Ticket.statusOptions.' . TicketModel::TICKET_STATUS_OPEN => TicketModel::TICKET_STATUS_OPEN, | |||
'field.Ticket.statusOptions.' . TicketModel::TICKET_STATUS_BEING_PROCESSED => TicketModel::TICKET_STATUS_BEING_PROCESSED, | |||
'field.Ticket.statusOptions.' . TicketModel::TICKET_STATUS_CLOSED => TicketModel::TICKET_STATUS_CLOSED, | |||
), | |||
[ | |||
'choices' => $this->translatorAdmin->transChoices(TicketModel::getChoicesStatus(),TicketModel::class), | |||
'required' => true, | |||
'expanded' => true | |||
) | |||
'expanded' => true, | |||
'label' => false, | |||
] | |||
); | |||
} | |||
@@ -41,8 +41,7 @@ class TicketStatusType extends AbstractType | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'data_class' => $this->em->getClassMetadata(TicketInterface::class)->getName(), | |||
'translation_domain' => 'lcshop' | |||
'data_class' => $this->em->getEntityName(TicketInterface::class), | |||
] | |||
); | |||
} |
@@ -1,59 +0,0 @@ | |||
<?php | |||
namespace Lc\SovBundle\Form\Ticket; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\Form\FormEvent; | |||
use Symfony\Component\Form\FormEvents; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
use Lc\SovBundle\Model\Ticket\TicketModel; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
class TicketTypeType extends AbstractType | |||
{ | |||
protected $em; | |||
public function __construct(EntityManagerInterface $em) | |||
{ | |||
$this->em = $em; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$builder->addEventListener( | |||
FormEvents::PRE_SET_DATA, | |||
function (FormEvent $event) { | |||
$builder = $event->getForm()->getParent(); | |||
$builder->add( | |||
'type', | |||
ChoiceType::class, | |||
[ | |||
'label' => 'field.Ticket.type', | |||
'multiple' => false, | |||
'expanded' => false, | |||
'choices' => [ | |||
'field.Ticket.typeOptions.' . TicketModel::TYPE_GENERAL_QUESTION => TicketModel::TYPE_GENERAL_QUESTION, | |||
'field.Ticket.typeOptions.' . TicketModel::TYPE_TECHNICAL_PROBLEM => TicketModel::TYPE_TECHNICAL_PROBLEM, | |||
], | |||
'translation_domain' => 'lcshop', | |||
] | |||
); | |||
} | |||
); | |||
} | |||
public function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'data_class' => $this->em->getClassMetadata(TicketInterface::class)->getName(), | |||
'translation_domain' => 'lcshop' | |||
] | |||
); | |||
} | |||
} |
@@ -163,7 +163,16 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
public function getStatusLabel(): string | |||
{ | |||
return 'field.Ticket.statusOptions.' . $this->getStatus(); | |||
return 'entity.Ticket.statusOptions.' . $this->getStatus(); | |||
} | |||
public function getChoicesStatus(): array | |||
{ | |||
return [ | |||
'entity.Ticket.fields.statusOptions.' . TicketModel::TICKET_STATUS_OPEN => TicketModel::TICKET_STATUS_OPEN, | |||
'entity.Ticket.fields.statusOptions.' . TicketModel::TICKET_STATUS_BEING_PROCESSED => TicketModel::TICKET_STATUS_BEING_PROCESSED, | |||
'entity.Ticket.fields.statusOptions.' . TicketModel::TICKET_STATUS_CLOSED => TicketModel::TICKET_STATUS_CLOSED, | |||
]; | |||
} | |||
public function getSubject(): ?string |
@@ -0,0 +1 @@ | |||
import './ticket.js' |
@@ -0,0 +1,17 @@ | |||
jQuery(document).ready(function () { | |||
$('.ticket-status').on("change", function () { | |||
$.ajax({ | |||
url: $('#ticketStatusForm').prop('action'), | |||
method: "POST", | |||
data: $('#ticketStatusForm').serialize(), | |||
dataType: "json", | |||
success: function (data) { | |||
if (data.success) { | |||
Notification.add('success', 'Le status a bien été mise à jour.'); | |||
} else { | |||
Notification.add('danger', 'Une erreur est survenue.'); | |||
} | |||
} | |||
}); | |||
}); | |||
}); |
@@ -79,6 +79,11 @@ entity: | |||
open: Ouvert | |||
being-processed: En attente | |||
closed: Fermé | |||
TicketModel: | |||
fields: | |||
open: Ouvert | |||
being-processed: En attente | |||
closed: Fermé | |||
TicketMessage: | |||
fields: | |||
message: Votre réponse |
@@ -6,7 +6,6 @@ | |||
{% endblock %} | |||
{% block main %} | |||
{{ dump() }} | |||
<div class="row"> | |||
<div class="col-4"> | |||
{% embed '@LcSov/adminlte/embed/infobox.html.twig' %} | |||
@@ -14,7 +13,12 @@ | |||
{% block icon %}fa fa-toggle-on{% endblock %} | |||
{% block title %}Status{% endblock %} | |||
{% block content %} | |||
{{ entity.instance.status }} | |||
{% form_theme form_ticket_status '@LcSov/adminlte/crud/form_theme.html.twig' %} | |||
{{ form_start(form_ticket_status,{'attr' : {'id' : 'ticketStatusForm'}}) }} | |||
{% for field in form_ticket_status.status %} | |||
{{ form_widget(field, {'attr': {"class" : 'ticket-status'}}) }} | |||
{% endfor %} | |||
{{ form_end(form_ticket_status) }} | |||
{% endblock %} | |||
{% endembed %} | |||
@@ -23,12 +27,12 @@ | |||
{% block icon %}fa fa-user{% endblock %} | |||
{% block title %}Utilisateur{% endblock %} | |||
{% block content %} | |||
{{ entity.instance.getUserInfosTicket() }} | |||
{{ ticket.getUserInfosTicket() }} | |||
{% endblock %} | |||
{% endembed %} | |||
{{ macro.infobox('Date',entity.instance.createdAt|date('d/m/Y'), "yellow", "fa fa-calendar") }} | |||
{{ macro.infobox('Catégorie',entity.instance.getTypeLabel()|trans({},'admin'), "green", "fa fa-archive") }} | |||
{{ macro.infobox('Date',ticket.createdAt|date('d/m/Y'), "yellow", "fa fa-calendar") }} | |||
{{ macro.infobox('Catégorie',ticket.getTypeLabel()|trans({},'admin'), "green", "fa fa-archive") }} | |||
</div> | |||
<div class="col-8"> | |||
{% embed '@LcSov/adminlte/embed/card.html.twig' %} | |||
@@ -42,7 +46,7 @@ | |||
{% block body_wrapper %} | |||
<div class="card-body row"> | |||
<div class="col-12 direct-chat-primary"> | |||
{% for message in entity.instance.ticketMessages %} | |||
{% for message in ticket.ticketMessages %} | |||
<div class="direct-chat-msg {{ message.answerByAdmin ? 'right' }}"> | |||
<div class="direct-chat-infos clearfix"> | |||
<div class="direct-chat-name {{ message.answerByAdmin ? 'float-right' : 'float-left' }}"> |
@@ -34,27 +34,37 @@ class TranslatorAdmin | |||
public function transField($fieldName, $entityClass): string | |||
{ | |||
return $this->transEntityThenDefault( | |||
$this->buildTransIdField($fieldName, $entityClass), | |||
$this->buildTransIdField($fieldName, $entityClass, true) | |||
$this->buildTransIdField($fieldName, $entityClass), | |||
$this->buildTransIdField($fieldName, $entityClass, true) | |||
); | |||
} | |||
public function transChoices($choices, $entityClass): array | |||
{ | |||
$newChoices = []; | |||
foreach ($choices as $key => $choice) { | |||
$newChoices[$this->trans($key)] = $choice; | |||
} | |||
return $newChoices; | |||
} | |||
public function transHelp($fieldName, $entityClass): string | |||
{ | |||
$fieldName = $fieldName . '_help'; | |||
return $this->transEntityThenDefault( | |||
$this->buildTransIdField($fieldName, $entityClass), | |||
$this->buildTransIdField($fieldName, $entityClass, true), | |||
true | |||
$this->buildTransIdField($fieldName, $entityClass), | |||
$this->buildTransIdField($fieldName, $entityClass, true), | |||
true | |||
); | |||
} | |||
public function transPanel($panelName, $entityClass): string | |||
{ | |||
return $this->transEntityThenDefault( | |||
$this->buildTransIdPanel($panelName, $entityClass), | |||
$this->buildTransIdPanel($panelName, $entityClass, true) | |||
$this->buildTransIdPanel($panelName, $entityClass), | |||
$this->buildTransIdPanel($panelName, $entityClass, true) | |||
); | |||
} | |||
@@ -67,8 +77,8 @@ class TranslatorAdmin | |||
if ($entityName) { | |||
$baseIdEntityLabel = 'entity.' . $entityName; | |||
$paramsTranslation = [ | |||
'%label%' => $this->trans($baseIdEntityLabel . '.label'), | |||
'%label_plurial%' => $this->trans($baseIdEntityLabel . '.label_plurial'), | |||
'%label%' => $this->trans($baseIdEntityLabel . '.label'), | |||
'%label_plurial%' => $this->trans($baseIdEntityLabel . '.label_plurial'), | |||
]; | |||
} | |||
@@ -77,8 +87,8 @@ class TranslatorAdmin | |||
} | |||
return $this->trans( | |||
'title.' . $pageName, | |||
$paramsTranslation | |||
'title.' . $pageName, | |||
$paramsTranslation | |||
); | |||
} | |||