Procházet zdrojové kódy

Finalisation tableau de bord + ticket

feature/symfony6.1
Fab před 2 roky
rodič
revize
69875a62d9
24 změnil soubory, kde provedl 551 přidání a 101 odebrání
  1. +11
    -1
      Container/Ticket/TicketContainer.php
  2. +9
    -1
      Controller/AbstractAdminController.php
  3. +45
    -42
      Controller/Ticket/TicketAdminController.php
  4. +39
    -8
      Controller/User/UserAdminController.php
  5. +2
    -0
      Definition/ActionDefinition.php
  6. +2
    -2
      Definition/Field/Site/NewsFieldDefinition.php
  7. +106
    -0
      Definition/Field/Ticket/TicketFieldDefinition.php
  8. +1
    -14
      Field/Filter/ChoiceFilter.php
  9. +11
    -12
      Field/Filter/FilterManager.php
  10. +3
    -3
      Field/Filter/FilterTrait.php
  11. +48
    -0
      Field/Filter/Ticket/EmailTicketFilter.php
  12. +48
    -0
      Field/Filter/Ticket/FirstnameTicketFilter.php
  13. +48
    -0
      Field/Filter/Ticket/LastnameTicketFilter.php
  14. +93
    -0
      Form/Ticket/TicketAdminFormType.php
  15. +3
    -6
      Form/Ticket/TicketFormType.php
  16. +45
    -0
      Form/Ticket/TicketMessageAdminType.php
  17. +1
    -0
      Model/Ticket/TicketModel.php
  18. +14
    -0
      Repository/Ticket/TicketRepositoryQuery.php
  19. +1
    -1
      Resources/translations/admin.fr.yaml
  20. +10
    -7
      Resources/views/admin/ticket/field/lastmessage.html.twig
  21. +2
    -0
      Resources/views/admin/ticket/field/status.html.twig
  22. +1
    -1
      Resources/views/admin/ticket/macro.html.twig
  23. +5
    -1
      Resources/views/adminlte/macro/badge.html.twig
  24. +3
    -2
      Solver/Ticket/TicketSolver.php

+ 11
- 1
Container/Ticket/TicketContainer.php Zobrazit soubor

namespace Lc\SovBundle\Container\Ticket; namespace Lc\SovBundle\Container\Ticket;


use Lc\SovBundle\Builder\Ticket\TicketBuilder; use Lc\SovBundle\Builder\Ticket\TicketBuilder;
use Lc\SovBundle\Definition\Field\Ticket\TicketFieldDefinition;
use Lc\SovBundle\Factory\Ticket\TicketFactory; use Lc\SovBundle\Factory\Ticket\TicketFactory;
use Lc\SovBundle\Repository\Ticket\TicketRepositoryQuery; use Lc\SovBundle\Repository\Ticket\TicketRepositoryQuery;
use Lc\SovBundle\Repository\Ticket\TicketStore; use Lc\SovBundle\Repository\Ticket\TicketStore;
protected TicketRepositoryQuery $repositoryQuery; protected TicketRepositoryQuery $repositoryQuery;
protected TicketStore $store; protected TicketStore $store;
protected TicketSolver $solver; protected TicketSolver $solver;
protected TicketFieldDefinition $fieldDefinition;


public function __construct( public function __construct(
TicketFactory $factory, TicketFactory $factory,
TicketBuilder $builder, TicketBuilder $builder,
TicketRepositoryQuery $repositoryQuery, TicketRepositoryQuery $repositoryQuery,
TicketStore $store, TicketStore $store,
TicketSolver $solver
TicketSolver $solver,
TicketFieldDefinition $fieldDefinition
) { ) {
$this->factory = $factory; $this->factory = $factory;
$this->builder = $builder; $this->builder = $builder;
$this->repositoryQuery = $repositoryQuery; $this->repositoryQuery = $repositoryQuery;
$this->store = $store; $this->store = $store;
$this->solver = $solver; $this->solver = $solver;
$this->fieldDefinition = $fieldDefinition;
} }


public function getFactory(): TicketFactory public function getFactory(): TicketFactory
{ {
return $this->solver; return $this->solver;
} }


public function getFieldDefinition(): TicketFieldDefinition
{
return $this->fieldDefinition;
}
} }

+ 9
- 1
Controller/AbstractAdminController.php Zobrazit soubor

use ControllerTrait; use ControllerTrait;


protected FormInterface $filtersForm; protected FormInterface $filtersForm;
protected bool $isRepositoryQueryFiltered = false;


abstract public function getRepositoryQuery(): RepositoryQueryInterface; abstract public function getRepositoryQuery(): RepositoryQueryInterface;


return $this->redirect($url); return $this->redirect($url);
} }


public function isRepositoryQueryFiltered():bool{
if(($this->filtersForm && $this->filtersForm->isSubmitted()) || $this->isRepositoryQueryFiltered){
return true;
}else{
return false;
}
}
public function createIndexRepositoryQuery( public function createIndexRepositoryQuery(
SearchDto $searchDto, SearchDto $searchDto,
EntityDto $entityDto, EntityDto $entityDto,


$this->filtersForm->handleRequest($searchDto->getRequest()); $this->filtersForm->handleRequest($searchDto->getRequest());


$filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto);
$this->isRepositoryQueryFiltered = $filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto);
return $repositoryQuery; return $repositoryQuery;
} }



+ 45
- 42
Controller/Ticket/TicketAdminController.php Zobrazit soubor

namespace Lc\SovBundle\Controller\Ticket; namespace Lc\SovBundle\Controller\Ticket;


use Doctrine\ORM\EntityManagerInterface; 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\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets; use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; 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\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Lc\SovBundle\Factory\Ticket\TicketFactoryInterface; use Lc\SovBundle\Factory\Ticket\TicketFactoryInterface;
use Lc\SovBundle\Factory\Ticket\TicketMessageFactory; use Lc\SovBundle\Factory\Ticket\TicketMessageFactory;
use Lc\SovBundle\Factory\Ticket\TicketMessageFactoryInterface; use Lc\SovBundle\Factory\Ticket\TicketMessageFactoryInterface;
use Lc\SovBundle\Form\Ticket\TicketAdminFormType;
use Lc\SovBundle\Form\Ticket\TicketFormType; use Lc\SovBundle\Form\Ticket\TicketFormType;
use Lc\SovBundle\Form\Ticket\TicketMessageFormType; use Lc\SovBundle\Form\Ticket\TicketMessageFormType;
use Lc\SovBundle\Form\Ticket\TicketStatusType; use Lc\SovBundle\Form\Ticket\TicketStatusType;
return $this->getTicketContainer()->getFactory()->create(); 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 public function configureAssets(Assets $assets): Assets
{ {
$assets = parent::configureAssets($assets); $assets = parent::configureAssets($assets);


public function configureFields(string $pageName): iterable 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 public function configureActions(Actions $actions): Actions
return parent::configureActions($actions); 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) public function new(AdminContext $context)
{ {
$adminUrlGenerator = $this->get(AdminUrlGenerator::class); $adminUrlGenerator = $this->get(AdminUrlGenerator::class);


$ticket = $this->createEntity($context->getEntity()->getFqcn()); $ticket = $this->createEntity($context->getEntity()->getFqcn());


$form = $this->createForm(TicketFormType::class, $ticket);
$form = $this->createForm(TicketAdminFormType::class, $ticket);


$form->handleRequest($context->getRequest()); $form->handleRequest($context->getRequest());
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
} }




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 = $this->createForm(TicketStatusType::class, $ticket);
$formTicketStatusForm->handleRequest($request);
$formTicketStatusForm->handleRequest($context->getRequest());


$success = false; $success = false;
if ($formTicketStatusForm->isSubmitted() && $formTicketStatusForm->isValid()) { if ($formTicketStatusForm->isSubmitted() && $formTicketStatusForm->isValid()) {
$this->get('em')->persist($ticket);
$this->get('em')->flush();
$entityManager->update($ticket);
$entityManager->flush();
$success = true; $success = true;
} }



+ 39
- 8
Controller/User/UserAdminController.php Zobrazit soubor



namespace Lc\SovBundle\Controller\User; 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\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\SovBundle\Container\User\UserContainer; use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Controller\AbstractAdminController; use Lc\SovBundle\Controller\AbstractAdminController;
use Lc\SovBundle\Definition\ActionDefinition;
use Lc\SovBundle\Definition\RolesDefinition; use Lc\SovBundle\Definition\RolesDefinition;
use Lc\SovBundle\Definition\RolesDefinitionInterface; use Lc\SovBundle\Definition\RolesDefinitionInterface;
use Lc\SovBundle\Doctrine\EntityManager; use Lc\SovBundle\Doctrine\EntityManager;
{ {
protected RolesDefinitionInterface $rolesDefinition; 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 public function configureFields(string $pageName): iterable

+ 2
- 0
Definition/ActionDefinition.php Zobrazit soubor

public const SAVE_AND_ADD_ANOTHER = 'saveAndAddAnother'; public const SAVE_AND_ADD_ANOTHER = 'saveAndAddAnother';
public const SAVE_AND_CONTINUE = 'saveAndContinue'; public const SAVE_AND_CONTINUE = 'saveAndContinue';
public const SAVE_AND_RETURN = 'saveAndReturn'; public const SAVE_AND_RETURN = 'saveAndReturn';
public const SWITCH_USER = 'switchUser';

} }

+ 2
- 2
Definition/Field/Site/NewsFieldDefinition.php Zobrazit soubor

use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField; use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition; use Lc\SovBundle\Definition\Field\AbstractFieldDefinition;
use Lc\SovBundle\Field\BooleanField; use Lc\SovBundle\Field\BooleanField;
use Lc\SovBundle\Field\CKEditorField;
use Lc\SovBundle\Field\ImageManagerField; use Lc\SovBundle\Field\ImageManagerField;


class NewsFieldDefinition extends AbstractFieldDefinition class NewsFieldDefinition extends AbstractFieldDefinition
'newsletter' => AssociationField::new('newsletter')->setSortable(true), 'newsletter' => AssociationField::new('newsletter')->setSortable(true),
'image' => ImageManagerField::new('image'), 'image' => ImageManagerField::new('image'),
'position' => NumberField::new('position'), 'position' => NumberField::new('position'),
'description' => TextEditorField::new('description'),
'description' => CKEditorField::new('description'),
'isSent' => BooleanField::new('isSent')->setSortable(true), 'isSent' => BooleanField::new('isSent')->setSortable(true),
]; ];
} }

+ 106
- 0
Definition/Field/Ticket/TicketFieldDefinition.php Zobrazit soubor

<?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(),
];
}

}

+ 1
- 14
Field/Filter/ChoiceFilter.php Zobrazit soubor

{ {
$fieldProperty = $this->getFieldProperty($fieldDto); $fieldProperty = $this->getFieldProperty($fieldDto);
if ($filteredValue !== null) { 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( $repositoryQuery->andWhere(
'.'.$fieldProperty.' LIKE :'.$fieldProperty.'' '.'.$fieldProperty.' LIKE :'.$fieldProperty.''
); );
$repositoryQuery->setParameter($fieldProperty, '%'.$filteredValue.'%');
$repositoryQuery->setParameter($fieldProperty, $filteredValue);


} }
} }

+ 11
- 12
Field/Filter/FilterManager.php Zobrazit soubor

class FilterManager class FilterManager
{ {
protected $em; protected $em;
protected bool $isFiltered = false;


use FilterTrait; use FilterTrait;


} }




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) { foreach ($fields as $field) {
$fieldDto->getProperty(), $fieldDto->getProperty(),
'dateEnd' 'dateEnd'
); );
if($filteredValue['dateStart'] || $filteredValue['dateEnd']){
$this->isFiltered = true;
}
} else { } else {
$filteredValue['value'] = $this->getFilteredValue( $filteredValue['value'] = $this->getFilteredValue(
$filtersForm, $filtersForm,
$entityDto->getFqcn(), $entityDto->getFqcn(),
$fieldDto->getProperty() $fieldDto->getProperty()
); );
if($filteredValue['value'] ){
$this->isFiltered = true;
}
} }

$this->applyFilter($repositoryQuery, $fieldDto, $filteredValue); $this->applyFilter($repositoryQuery, $fieldDto, $filteredValue);
} }
} }
} }
return $this->isFiltered;
} }




$customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']); $customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
} else { } else {


switch ($this->guessFormType($fieldDto)) {
switch ($fieldDto->getFormType()) {


case CheckboxType::class: case CheckboxType::class:
$checkboxFilter = new CheckboxFilter(); $checkboxFilter = new CheckboxFilter();
} }
} }



protected function guessFormType(FieldDto $fieldDto)
{
if ($fieldDto->getCustomOption('filter_type')) {
return $fieldDto->getCustomOption('filter_type');
} else {
return $fieldDto->getFormType();
}

}
} }

+ 3
- 3
Field/Filter/FilterTrait.php Zobrazit soubor

{ {
$property = $fieldDto->getProperty(); $property = $fieldDto->getProperty();
//TODO pas forcément utile, à discuter //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; return $property;
} }



+ 48
- 0
Field/Filter/Ticket/EmailTicketFilter.php Zobrazit soubor

<?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 . '%');
}
}

}

+ 48
- 0
Field/Filter/Ticket/FirstnameTicketFilter.php Zobrazit soubor

<?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 . '%');
}
}

}

+ 48
- 0
Field/Filter/Ticket/LastnameTicketFilter.php Zobrazit soubor

<?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 . '%');
}
}

}

+ 93
- 0
Form/Ticket/TicketAdminFormType.php Zobrazit soubor

<?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),
]
);
}
}

+ 3
- 6
Form/Ticket/TicketFormType.php Zobrazit soubor

{ {
protected EntityManager $entityManager; protected EntityManager $entityManager;
protected TranslatorAdmin $translatorAdmin; protected TranslatorAdmin $translatorAdmin;
protected TicketSolver $ticketSolver;


public function __construct( public function __construct(
EntityManager $entityManager, EntityManager $entityManager,
TranslatorAdmin $translatorAdmin,
TicketSolver $ticketSolver
TranslatorAdmin $translatorAdmin
) { ) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->translatorAdmin = $translatorAdmin; $this->translatorAdmin = $translatorAdmin;
$this->ticketSolver = $ticketSolver;
} }


public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
[ [
'label' => 'Type', 'label' => 'Type',
'choices' => $this->translatorAdmin->transChoices( 'choices' => $this->translatorAdmin->transChoices(
$this->ticketSolver->getTypeChoices(),
TicketSolver::getTypeChoices(),
'Ticket', 'Ticket',
'type' 'type'
), ),
] ]
); );
} }
}
}

+ 45
- 0
Form/Ticket/TicketMessageAdminType.php Zobrazit soubor

<?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),
]
);
}
}

+ 1
- 0
Model/Ticket/TicketModel.php Zobrazit soubor



const TICKET_STATUS_OPEN = 'open'; const TICKET_STATUS_OPEN = 'open';
const TICKET_STATUS_BEING_PROCESSED = 'being-processed'; const TICKET_STATUS_BEING_PROCESSED = 'being-processed';
const TICKET_STATUS_PROCESSED = 'processed';
const TICKET_STATUS_CLOSED = 'closed'; const TICKET_STATUS_CLOSED = 'closed';


/** /**

+ 14
- 0
Repository/Ticket/TicketRepositoryQuery.php Zobrazit soubor



class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRepositoryQueryInterface class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRepositoryQueryInterface
{ {
protected $isJoinUser = false;


public function __construct(TicketRepository $repository, PaginatorInterface $paginator) public function __construct(TicketRepository $repository, PaginatorInterface $paginator)
{ {
parent::__construct($repository, 'r', $paginator); parent::__construct($repository, 'r', $paginator);
->setParameter('user', $user); ->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 public function filterByStatus($statusArray): self
{ {
return $this return $this

+ 1
- 1
Resources/translations/admin.fr.yaml Zobrazit soubor

default: default:
fields: fields:
id: Id id: Id
createdAt: Créé à
createdAt: Créé le
user: Utilisateur user: Utilisateur
firstname: Prénom firstname: Prénom
lastname: Nom lastname: Nom

+ 10
- 7
Resources/views/admin/ticket/field/lastmessage.html.twig Zobrazit soubor

{#{% 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 }}

+ 2
- 0
Resources/views/admin/ticket/field/status.html.twig Zobrazit soubor

{{ macro.badge_success(status|sov_trans_admin_choice('status','Ticket')) }} {{ macro.badge_success(status|sov_trans_admin_choice('status','Ticket')) }}
{% elseif status == 'being-processed' %} {% elseif status == 'being-processed' %}
{{ macro.badge_warning(status|sov_trans_admin_choice('status','Ticket')) }} {{ 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' %} {% elseif status == 'closed' %}
{{ macro.badge_danger(status|sov_trans_admin_choice('status','Ticket')) }} {{ macro.badge_danger(status|sov_trans_admin_choice('status','Ticket')) }}
{% endif %} {% endif %}

+ 1
- 1
Resources/views/admin/ticket/macro.html.twig Zobrazit soubor

<th>Sujet</th> <th>Sujet</th>
<th>Statut</th> <th>Statut</th>
<th>Dernier message</th> <th>Dernier message</th>
<th></th>
<th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

+ 5
- 1
Resources/views/adminlte/macro/badge.html.twig Zobrazit soubor

{{ _self.badge('danger', title) }} {{ _self.badge('danger', title) }}
{% endmacro %} {% endmacro %}


{% macro badge_info(title) %}
{{ _self.badge('info', title) }}
{% endmacro %}

{% macro badge(status, title) %} {% macro badge(status, title) %}
<span class="badge badge-{{ status }}">{{ title }}</span> <span class="badge badge-{{ status }}">{{ title }}</span>
{% endmacro %}
{% endmacro %}

+ 3
- 2
Solver/Ticket/TicketSolver.php Zobrazit soubor



class TicketSolver class TicketSolver
{ {
public function getTypeChoices(): array
public static function getTypeChoices(): array
{ {
return [ return [
TicketModel::TYPE_GENERAL_QUESTION, TicketModel::TYPE_GENERAL_QUESTION,
]; ];
} }


public function getStatusChoices(): array
public static function getStatusChoices(): array
{ {
return [ return [
TicketModel::TICKET_STATUS_OPEN, TicketModel::TICKET_STATUS_OPEN,
TicketModel::TICKET_STATUS_BEING_PROCESSED, TicketModel::TICKET_STATUS_BEING_PROCESSED,
TicketModel::TICKET_STATUS_PROCESSED,
TicketModel::TICKET_STATUS_CLOSED, TicketModel::TICKET_STATUS_CLOSED,
]; ];
} }

Načítá se…
Zrušit
Uložit