@@ -3,6 +3,7 @@ | |||
namespace Lc\SovBundle\Container\Ticket; | |||
use Lc\SovBundle\Builder\Ticket\TicketBuilder; | |||
use Lc\SovBundle\Definition\Field\Ticket\TicketFieldDefinition; | |||
use Lc\SovBundle\Factory\Ticket\TicketFactory; | |||
use Lc\SovBundle\Repository\Ticket\TicketRepositoryQuery; | |||
use Lc\SovBundle\Repository\Ticket\TicketStore; | |||
@@ -15,19 +16,22 @@ class TicketContainer | |||
protected TicketRepositoryQuery $repositoryQuery; | |||
protected TicketStore $store; | |||
protected TicketSolver $solver; | |||
protected TicketFieldDefinition $fieldDefinition; | |||
public function __construct( | |||
TicketFactory $factory, | |||
TicketBuilder $builder, | |||
TicketRepositoryQuery $repositoryQuery, | |||
TicketStore $store, | |||
TicketSolver $solver | |||
TicketSolver $solver, | |||
TicketFieldDefinition $fieldDefinition | |||
) { | |||
$this->factory = $factory; | |||
$this->builder = $builder; | |||
$this->repositoryQuery = $repositoryQuery; | |||
$this->store = $store; | |||
$this->solver = $solver; | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public function getFactory(): TicketFactory | |||
@@ -54,4 +58,10 @@ class TicketContainer | |||
{ | |||
return $this->solver; | |||
} | |||
public function getFieldDefinition(): TicketFieldDefinition | |||
{ | |||
return $this->fieldDefinition; | |||
} | |||
} |
@@ -62,6 +62,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
use ControllerTrait; | |||
protected FormInterface $filtersForm; | |||
protected bool $isRepositoryQueryFiltered = false; | |||
abstract public function getRepositoryQuery(): RepositoryQueryInterface; | |||
@@ -332,6 +333,13 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
return $this->redirect($url); | |||
} | |||
public function isRepositoryQueryFiltered():bool{ | |||
if(($this->filtersForm && $this->filtersForm->isSubmitted()) || $this->isRepositoryQueryFiltered){ | |||
return true; | |||
}else{ | |||
return false; | |||
} | |||
} | |||
public function createIndexRepositoryQuery( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
@@ -370,7 +378,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$this->filtersForm->handleRequest($searchDto->getRequest()); | |||
$filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto); | |||
$this->isRepositoryQueryFiltered = $filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto); | |||
return $repositoryQuery; | |||
} | |||
@@ -3,14 +3,19 @@ | |||
namespace Lc\SovBundle\Controller\Ticket; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; | |||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; | |||
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\Context\AdminContext; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; | |||
@@ -21,6 +26,7 @@ use Lc\SovBundle\Factory\Ticket\TicketFactory; | |||
use Lc\SovBundle\Factory\Ticket\TicketFactoryInterface; | |||
use Lc\SovBundle\Factory\Ticket\TicketMessageFactory; | |||
use Lc\SovBundle\Factory\Ticket\TicketMessageFactoryInterface; | |||
use Lc\SovBundle\Form\Ticket\TicketAdminFormType; | |||
use Lc\SovBundle\Form\Ticket\TicketFormType; | |||
use Lc\SovBundle\Form\Ticket\TicketMessageFormType; | |||
use Lc\SovBundle\Form\Ticket\TicketStatusType; | |||
@@ -45,6 +51,13 @@ abstract class TicketAdminController extends AbstractAdminController | |||
return $this->getTicketContainer()->getFactory()->create(); | |||
} | |||
public function configureCrud(Crud $crud): Crud | |||
{ | |||
$crud = parent::configureCrud($crud); // TODO: Change the autogenerated stub | |||
$crud->setDefaultSort(array('updatedAt'=> 'DESC')); | |||
return $crud; | |||
} | |||
public function configureAssets(Assets $assets): Assets | |||
{ | |||
$assets = parent::configureAssets($assets); | |||
@@ -56,41 +69,7 @@ abstract class TicketAdminController extends AbstractAdminController | |||
public function configureFields(string $pageName): iterable | |||
{ | |||
$translatorAdmin = $this->get(TranslatorAdmin::class); | |||
return [ | |||
IntegerField::new('id') | |||
->hideOnForm(), | |||
DateField::new('createdAt')->setFormat('short') | |||
->hideOnForm(), | |||
TextField::new('visitorFirstname') | |||
->setTemplatePath('@LcSov/admin/ticket/field/firstname.html.twig') | |||
->hideOnForm(), | |||
TextField::new('visitorLastname') | |||
->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig') | |||
->hideOnForm(), | |||
TextField::new('visitorEmail') | |||
->setTemplatePath('@LcSov/admin/ticket/field/email.html.twig') | |||
->hideOnForm(), | |||
AssociationField::new('user') | |||
->hideOnIndex(), | |||
TextField::new('subject'), | |||
TextField::new('lastMessage') | |||
->setTemplatePath('@LcSov/admin/ticket/field/lastmessage.html.twig') | |||
->hideOnForm(), | |||
ChoiceField::new('type') | |||
->autocomplete() | |||
->setChoices( | |||
$translatorAdmin->transChoices($this->get(TicketContainer::class)->getSolver()->getTypeChoices(), 'Ticket', 'type') | |||
), | |||
ChoiceField::new('status') | |||
->autocomplete() | |||
->setChoices( | |||
$translatorAdmin->transChoices($this->get(TicketContainer::class)->getSolver()->getStatusChoices(), 'Ticket', 'status') | |||
) | |||
->setTemplatePath('@LcSov/admin/ticket/field/status.html.twig') | |||
->hideOnForm(), | |||
]; | |||
return $this->getTicketContainer()->getFieldDefinition()->getFields($pageName); | |||
} | |||
public function configureActions(Actions $actions): Actions | |||
@@ -102,13 +81,37 @@ abstract class TicketAdminController extends AbstractAdminController | |||
return parent::configureActions($actions); | |||
} | |||
public function createIndexRepositoryQuery( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): RepositoryQueryInterface { | |||
$repositoryQuery = parent::createIndexRepositoryQuery( | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
); | |||
if(!$this->isRepositoryQueryFiltered()){ | |||
$repositoryQuery->filterByStatus(array( | |||
TicketModel::TICKET_STATUS_OPEN, | |||
TicketModel::TICKET_STATUS_BEING_PROCESSED | |||
)); | |||
} | |||
return $repositoryQuery; | |||
} | |||
public function new(AdminContext $context) | |||
{ | |||
$adminUrlGenerator = $this->get(AdminUrlGenerator::class); | |||
$ticket = $this->createEntity($context->getEntity()->getFqcn()); | |||
$form = $this->createForm(TicketFormType::class, $ticket); | |||
$form = $this->createForm(TicketAdminFormType::class, $ticket); | |||
$form->handleRequest($context->getRequest()); | |||
if ($form->isSubmitted() && $form->isValid()) { | |||
@@ -173,18 +176,18 @@ abstract class TicketAdminController extends AbstractAdminController | |||
} | |||
public function ticketStatusAction() | |||
public function ticketStatusAction(AdminContext $context, EntityManagerInterface $entityManager) | |||
{ | |||
$request = $this->get('request')->getMasterRequest(); | |||
$ticket = $request->attributes->get('easyadmin_context')->getEntity()->getInstance(); | |||
$ticket = $context->getEntity()->getInstance(); | |||
$formTicketStatusForm = $this->createForm(TicketStatusType::class, $ticket); | |||
$formTicketStatusForm->handleRequest($request); | |||
$formTicketStatusForm->handleRequest($context->getRequest()); | |||
$success = false; | |||
if ($formTicketStatusForm->isSubmitted() && $formTicketStatusForm->isValid()) { | |||
$this->get('em')->persist($ticket); | |||
$this->get('em')->flush(); | |||
$entityManager->update($ticket); | |||
$entityManager->flush(); | |||
$success = true; | |||
} | |||
@@ -2,11 +2,16 @@ | |||
namespace Lc\SovBundle\Controller\User; | |||
use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use Lc\SovBundle\Container\User\UserContainer; | |||
use Lc\SovBundle\Controller\AbstractAdminController; | |||
use Lc\SovBundle\Definition\ActionDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinitionInterface; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
@@ -19,14 +24,40 @@ abstract class UserAdminController extends AbstractAdminController | |||
{ | |||
protected RolesDefinitionInterface $rolesDefinition; | |||
public function __construct( | |||
SessionInterface $session, | |||
RequestStack $request, | |||
EntityManager $em, | |||
TranslatorAdmin $translatorAdmin, | |||
RolesDefinitionInterface $rolesDefinition | |||
) { | |||
$this->rolesDefinition = $rolesDefinition; | |||
public function buildIndexActions(Actions $actions): void | |||
{ | |||
parent::buildIndexActions($actions); // TODO: Change the autogenerated stub | |||
$actions->add(Crud::PAGE_INDEX, $this->getSwitchUserAction()); | |||
} | |||
public function getSwitchUserAction(): Action | |||
{ | |||
$switchAction = Action::new( | |||
ActionDefinition::SWITCH_USER, | |||
$this->get(TranslatorAdmin::class)->transAction(ActionDefinition::SWITCH_USER), | |||
'fa fa-fw fa-user-secret' | |||
) | |||
->linkToCrudAction(ActionDefinition::SWITCH_USER) | |||
->setLabel($this->get(TranslatorAdmin::class)->transAction(ActionDefinition::SWITCH_USER)) | |||
->setCssClass('in-dropdown text-info action-confirm action_switch'); | |||
return $switchAction; | |||
} | |||
public function overrideEntitiesActions(?EntityCollection $entities): void | |||
{ | |||
parent::overrideEntitiesActions($entities); // TODO: Change the autogenerated stub | |||
foreach ($entities as $entity) { | |||
foreach ($entity->getActions() as $action){ | |||
if($action->getName() == ActionDefinition::SWITCH_USER){ | |||
$url = $this->generateUrl($this->getParameter('lc_sov.homepage_route'), array('_switch_user' => $entity->getInstance()->getEmail())); | |||
$action->setLinkUrl($url); | |||
} | |||
} | |||
} | |||
} | |||
public function configureFields(string $pageName): iterable |
@@ -15,4 +15,6 @@ class ActionDefinition { | |||
public const SAVE_AND_ADD_ANOTHER = 'saveAndAddAnother'; | |||
public const SAVE_AND_CONTINUE = 'saveAndContinue'; | |||
public const SAVE_AND_RETURN = 'saveAndReturn'; | |||
public const SWITCH_USER = 'switchUser'; | |||
} |
@@ -5,10 +5,10 @@ namespace Lc\SovBundle\Definition\Field\Site; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition; | |||
use Lc\SovBundle\Field\BooleanField; | |||
use Lc\SovBundle\Field\CKEditorField; | |||
use Lc\SovBundle\Field\ImageManagerField; | |||
class NewsFieldDefinition extends AbstractFieldDefinition | |||
@@ -50,7 +50,7 @@ class NewsFieldDefinition extends AbstractFieldDefinition | |||
'newsletter' => AssociationField::new('newsletter')->setSortable(true), | |||
'image' => ImageManagerField::new('image'), | |||
'position' => NumberField::new('position'), | |||
'description' => TextEditorField::new('description'), | |||
'description' => CKEditorField::new('description'), | |||
'isSent' => BooleanField::new('isSent')->setSortable(true), | |||
]; | |||
} |
@@ -0,0 +1,106 @@ | |||
<?php | |||
namespace Lc\SovBundle\Definition\Field\Ticket; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition; | |||
use Lc\SovBundle\Field\Filter\Ticket\EmailTicketFilter; | |||
use Lc\SovBundle\Field\Filter\Ticket\FirstnameTicketFilter; | |||
use Lc\SovBundle\Field\Filter\Ticket\LastnameTicketFilter; | |||
use Lc\SovBundle\Solver\Ticket\TicketSolver; | |||
class TicketFieldDefinition extends AbstractFieldDefinition | |||
{ | |||
public function configureIndex(): array | |||
{ | |||
return [ | |||
'id', | |||
'createdAt', | |||
'visitorFirstname', | |||
'visitorLastname', | |||
'visitorEmail', | |||
'subject', | |||
'updatedAt', | |||
'type', | |||
'status' | |||
]; | |||
} | |||
public function configureForm(): array | |||
{ | |||
return [ | |||
'user', | |||
'subject' | |||
]; | |||
} | |||
public function configurePanels(): array | |||
{ | |||
return []; | |||
} | |||
public function configureFields(): array | |||
{ | |||
return [ | |||
'id' => IdField::new('id') | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'createdAt' => DateTimeField::new('createdAt') | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'visitorFirstname' => TextField::new('visitorFirstname') | |||
->setTemplatePath('@LcSov/admin/ticket/field/firstname.html.twig') | |||
->setCustomOption('filter_fqcn', FirstnameTicketFilter::class) | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'visitorLastname' => TextField::new('visitorLastname') | |||
->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig') | |||
->setCustomOption('filter_fqcn', LastnameTicketFilter::class) | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'visitorEmail' => TextField::new('visitorEmail') | |||
->setTemplatePath('@LcSov/admin/ticket/field/email.html.twig') | |||
->setCustomOption('filter_fqcn', EmailTicketFilter::class) | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'user' => AssociationField::new('user') | |||
->hideOnIndex(), | |||
'subject' => TextField::new('subject') | |||
->setSortable(true), | |||
'updatedAt' => DateTimeField::new('updatedAt') | |||
->setTemplatePath('@LcSov/admin/ticket/field/lastmessage.html.twig') | |||
->setSortable(true) | |||
->hideOnForm(), | |||
'type' => ChoiceField::new('type') | |||
->autocomplete() | |||
->setSortable(true) | |||
->setChoices( | |||
$this->translatorAdmin->transChoices( | |||
TicketSolver::getTypeChoices(), | |||
'Ticket', | |||
'type' | |||
) | |||
), | |||
'status' => ChoiceField::new('status') | |||
->autocomplete() | |||
->setSortable(true) | |||
->setChoices( | |||
$this->translatorAdmin->transChoices( | |||
TicketSolver::getStatusChoices(), | |||
'Ticket', | |||
'status' | |||
) | |||
) | |||
->setTemplatePath('@LcSov/admin/ticket/field/status.html.twig') | |||
->hideOnForm(), | |||
]; | |||
} | |||
} |
@@ -53,23 +53,10 @@ class ChoiceFilter | |||
{ | |||
$fieldProperty = $this->getFieldProperty($fieldDto); | |||
if ($filteredValue !== null) { | |||
// if ($this->isRelationField($fieldProperty)) { | |||
// $aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||
// if (array_search($aliasRelation, $repositoryQuery->getAllAliases()) === false) { | |||
// $repositoryQuery->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||
// } | |||
// $repositoryQuery->andWhere( | |||
// $fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).'' | |||
// ); | |||
// $repositoryQuery->setParameter( | |||
// $this->getFieldPropertySnake($fieldProperty), | |||
// '%'.$filteredValue.'%' | |||
// ); | |||
// } else { | |||
$repositoryQuery->andWhere( | |||
'.'.$fieldProperty.' LIKE :'.$fieldProperty.'' | |||
); | |||
$repositoryQuery->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||
$repositoryQuery->setParameter($fieldProperty, $filteredValue); | |||
} | |||
} |
@@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
class FilterManager | |||
{ | |||
protected $em; | |||
protected bool $isFiltered = false; | |||
use FilterTrait; | |||
@@ -39,7 +40,7 @@ class FilterManager | |||
} | |||
public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto) | |||
public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto):bool | |||
{ | |||
foreach ($fields as $field) { | |||
@@ -65,17 +66,25 @@ class FilterManager | |||
$fieldDto->getProperty(), | |||
'dateEnd' | |||
); | |||
if($filteredValue['dateStart'] || $filteredValue['dateEnd']){ | |||
$this->isFiltered = true; | |||
} | |||
} else { | |||
$filteredValue['value'] = $this->getFilteredValue( | |||
$filtersForm, | |||
$entityDto->getFqcn(), | |||
$fieldDto->getProperty() | |||
); | |||
if($filteredValue['value'] ){ | |||
$this->isFiltered = true; | |||
} | |||
} | |||
$this->applyFilter($repositoryQuery, $fieldDto, $filteredValue); | |||
} | |||
} | |||
} | |||
return $this->isFiltered; | |||
} | |||
@@ -88,7 +97,7 @@ class FilterManager | |||
$customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']); | |||
} else { | |||
switch ($this->guessFormType($fieldDto)) { | |||
switch ($fieldDto->getFormType()) { | |||
case CheckboxType::class: | |||
$checkboxFilter = new CheckboxFilter(); | |||
@@ -183,14 +192,4 @@ class FilterManager | |||
} | |||
} | |||
protected function guessFormType(FieldDto $fieldDto) | |||
{ | |||
if ($fieldDto->getCustomOption('filter_type')) { | |||
return $fieldDto->getCustomOption('filter_type'); | |||
} else { | |||
return $fieldDto->getFormType(); | |||
} | |||
} | |||
} |
@@ -41,9 +41,9 @@ trait FilterTrait | |||
{ | |||
$property = $fieldDto->getProperty(); | |||
//TODO pas forcément utile, à discuter | |||
if ($fieldDto->getCustomOption('filter_on')) { | |||
$property = $property . '.' . $fieldDto->getCustomOption('filter_on'); | |||
} | |||
// if ($fieldDto->getCustomOption('filter_on')) { | |||
// $property = $property . '.' . $fieldDto->getCustomOption('filter_on'); | |||
// } | |||
return $property; | |||
} | |||
@@ -0,0 +1,48 @@ | |||
<?php | |||
namespace Lc\SovBundle\Field\Filter\Ticket; | |||
use Doctrine\ORM\EntityRepository; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Lc\SovBundle\Field\Filter\FilterTrait; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
/** | |||
* @author La clic ! <contact@laclic.fr> | |||
*/ | |||
class EmailTicketFilter | |||
{ | |||
use FilterTrait; | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
str_replace('.', '_', $fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
} | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null) | |||
{ | |||
$fieldProperty = $this->getFieldProperty($fieldDto); | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->joinUser(); | |||
$repositoryQuery->andWhere( | |||
'.' . $fieldProperty . ' LIKE :' . $fieldProperty . ' OR user.email LIKE :' . $fieldProperty | |||
); | |||
$repositoryQuery->setParameter($fieldProperty, '%' . $filteredValue . '%'); | |||
} | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
<?php | |||
namespace Lc\SovBundle\Field\Filter\Ticket; | |||
use Doctrine\ORM\EntityRepository; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Lc\SovBundle\Field\Filter\FilterTrait; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
/** | |||
* @author La clic ! <contact@laclic.fr> | |||
*/ | |||
class FirstnameTicketFilter | |||
{ | |||
use FilterTrait; | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
str_replace('.', '_', $fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
} | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null) | |||
{ | |||
$fieldProperty = $this->getFieldProperty($fieldDto); | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->joinUser(); | |||
$repositoryQuery->andWhere( | |||
'.' . $fieldProperty . ' LIKE :' . $fieldProperty . ' OR user.firstname LIKE :' . $fieldProperty | |||
); | |||
$repositoryQuery->setParameter($fieldProperty, '%' . $filteredValue . '%'); | |||
} | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
<?php | |||
namespace Lc\SovBundle\Field\Filter\Ticket; | |||
use Doctrine\ORM\EntityRepository; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Lc\SovBundle\Field\Filter\FilterTrait; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
/** | |||
* @author La clic ! <contact@laclic.fr> | |||
*/ | |||
class LastnameTicketFilter | |||
{ | |||
use FilterTrait; | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
str_replace('.', '_', $fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
} | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null) | |||
{ | |||
$fieldProperty = $this->getFieldProperty($fieldDto); | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->joinUser(); | |||
$repositoryQuery->andWhere( | |||
'.' . $fieldProperty . ' LIKE :' . $fieldProperty . ' OR user.lastname LIKE :' . $fieldProperty | |||
); | |||
$repositoryQuery->setParameter($fieldProperty, '%' . $filteredValue . '%'); | |||
} | |||
} | |||
} |
@@ -0,0 +1,93 @@ | |||
<?php | |||
namespace Lc\SovBundle\Form\Ticket; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketModel; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Solver\Ticket\TicketSolver; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | |||
use Symfony\Component\Form\Extension\Core\Type\SubmitType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class TicketAdminFormType extends AbstractType | |||
{ | |||
protected EntityManager $entityManager; | |||
protected TranslatorAdmin $translatorAdmin; | |||
public function __construct( | |||
EntityManager $entityManager, | |||
TranslatorAdmin $translatorAdmin | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$entityName = $this->entityManager->getEntityName(TicketInterface::class); | |||
$builder->add( | |||
'user', | |||
EntityType::class, | |||
[ | |||
'class' => $this->entityManager->getEntityName(UserInterface::class), | |||
] | |||
); | |||
$builder->add( | |||
'subject', | |||
TextType::class | |||
); | |||
$builder->add( | |||
'type', | |||
ChoiceType::class, | |||
[ | |||
'label' => 'Type', | |||
'choices' => $this->translatorAdmin->transChoices( | |||
TicketSolver::getTypeChoices(), | |||
'Ticket', | |||
'type' | |||
), | |||
] | |||
); | |||
$builder->add( | |||
'ticketMessages', | |||
CollectionType::class, | |||
[ | |||
'entry_type' => TicketMessageAdminType::class, | |||
'allow_add' => false, | |||
'label_attr' => ['class' => 'label-ticket'], | |||
] | |||
); | |||
$builder->add( | |||
'submit', | |||
SubmitType::class, | |||
[ | |||
'label' => $this->translatorAdmin->transAction('save') | |||
] | |||
); | |||
} | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'data_class' => $this->entityManager->getEntityName(TicketInterface::class), | |||
] | |||
); | |||
} | |||
} |
@@ -21,16 +21,13 @@ class TicketFormType extends AbstractType | |||
{ | |||
protected EntityManager $entityManager; | |||
protected TranslatorAdmin $translatorAdmin; | |||
protected TicketSolver $ticketSolver; | |||
public function __construct( | |||
EntityManager $entityManager, | |||
TranslatorAdmin $translatorAdmin, | |||
TicketSolver $ticketSolver | |||
TranslatorAdmin $translatorAdmin | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->translatorAdmin = $translatorAdmin; | |||
$this->ticketSolver = $ticketSolver; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
@@ -56,7 +53,7 @@ class TicketFormType extends AbstractType | |||
[ | |||
'label' => 'Type', | |||
'choices' => $this->translatorAdmin->transChoices( | |||
$this->ticketSolver->getTypeChoices(), | |||
TicketSolver::getTypeChoices(), | |||
'Ticket', | |||
'type' | |||
), | |||
@@ -93,4 +90,4 @@ class TicketFormType extends AbstractType | |||
] | |||
); | |||
} | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
<?php | |||
namespace Lc\SovBundle\Form\Ticket; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Model\Ticket\TicketMessageInterface; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\SubmitType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextareaType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class TicketMessageAdminType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $translatorAdmin; | |||
public function __construct(EntityManager $em, TranslatorAdmin $translatorAdmin) | |||
{ | |||
$this->em = $em; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$builder->add( | |||
'message', | |||
TextareaType::class, | |||
[ | |||
'required' => true | |||
] | |||
); | |||
} | |||
public function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'data_class' => $this->em->getEntityName(TicketMessageInterface::class), | |||
] | |||
); | |||
} | |||
} |
@@ -22,6 +22,7 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
const TICKET_STATUS_OPEN = 'open'; | |||
const TICKET_STATUS_BEING_PROCESSED = 'being-processed'; | |||
const TICKET_STATUS_PROCESSED = 'processed'; | |||
const TICKET_STATUS_CLOSED = 'closed'; | |||
/** |
@@ -8,6 +8,9 @@ use Lc\SovBundle\Repository\AbstractRepositoryQuery; | |||
class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRepositoryQueryInterface | |||
{ | |||
protected $isJoinUser = false; | |||
public function __construct(TicketRepository $repository, PaginatorInterface $paginator) | |||
{ | |||
parent::__construct($repository, 'r', $paginator); | |||
@@ -20,6 +23,17 @@ class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRep | |||
->setParameter('user', $user); | |||
} | |||
public function joinUser(): self | |||
{ | |||
if (!$this->isJoinUser) { | |||
$this->isJoinUser = true; | |||
return $this | |||
->leftJoin('.user', 'user'); | |||
} | |||
return $this; | |||
} | |||
public function filterByStatus($statusArray): self | |||
{ | |||
return $this |
@@ -106,7 +106,7 @@ entity: | |||
default: | |||
fields: | |||
id: Id | |||
createdAt: Créé à | |||
createdAt: Créé le | |||
user: Utilisateur | |||
firstname: Prénom | |||
lastname: Nom |
@@ -1,7 +1,10 @@ | |||
{#{% set ticketMessage = entity.instance.getLastMessage() %}#} | |||
{#{% if ticketMessage.answerByAdmin != true %}#} | |||
{# <span class="badge badge-danger">#} | |||
{# New#} | |||
{# </span>#} | |||
{#{% endif %}#} | |||
{#{{ ticketMessage.createdAt|date('d/m/Y H:i') }} par {{ ticketMessage.createdBy }} {{ ticketMessage.message }}#} | |||
{% if item is not defined %} | |||
{% set item = entity.instance %} | |||
{% endif %} | |||
{% set ticketMessage = ticket_container.solver.getLastMessage(item) %} | |||
{% if ticketMessage.answerByAdmin != true %} | |||
<span class="badge badge-danger"> | |||
New | |||
</span> | |||
{% endif %} | |||
{{ ticketMessage.createdAt|date('d/m/Y H:i') }} par {{ ticketMessage.createdBy }} |
@@ -6,6 +6,8 @@ | |||
{{ macro.badge_success(status|sov_trans_admin_choice('status','Ticket')) }} | |||
{% elseif status == 'being-processed' %} | |||
{{ macro.badge_warning(status|sov_trans_admin_choice('status','Ticket')) }} | |||
{% elseif status == 'processed' %} | |||
{{ macro.badge_info(status|sov_trans_admin_choice('status','Ticket')) }} | |||
{% elseif status == 'closed' %} | |||
{{ macro.badge_danger(status|sov_trans_admin_choice('status','Ticket')) }} | |||
{% endif %} |
@@ -5,7 +5,7 @@ | |||
<th>Sujet</th> | |||
<th>Statut</th> | |||
<th>Dernier message</th> | |||
<th></th> | |||
<th>Actions</th> | |||
</tr> | |||
</thead> | |||
<tbody> |
@@ -10,6 +10,10 @@ | |||
{{ _self.badge('danger', title) }} | |||
{% endmacro %} | |||
{% macro badge_info(title) %} | |||
{{ _self.badge('info', title) }} | |||
{% endmacro %} | |||
{% macro badge(status, title) %} | |||
<span class="badge badge-{{ status }}">{{ title }}</span> | |||
{% endmacro %} | |||
{% endmacro %} |
@@ -7,7 +7,7 @@ use Lc\SovBundle\Model\Ticket\TicketModel; | |||
class TicketSolver | |||
{ | |||
public function getTypeChoices(): array | |||
public static function getTypeChoices(): array | |||
{ | |||
return [ | |||
TicketModel::TYPE_GENERAL_QUESTION, | |||
@@ -15,11 +15,12 @@ class TicketSolver | |||
]; | |||
} | |||
public function getStatusChoices(): array | |||
public static function getStatusChoices(): array | |||
{ | |||
return [ | |||
TicketModel::TICKET_STATUS_OPEN, | |||
TicketModel::TICKET_STATUS_BEING_PROCESSED, | |||
TicketModel::TICKET_STATUS_PROCESSED, | |||
TicketModel::TICKET_STATUS_CLOSED, | |||
]; | |||
} |