use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore; | use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; | use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController; | use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent; | use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent; | use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException; | use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException; | use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory; | use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\FilterFactory; | use EasyCorp\Bundle\EasyAdminBundle\Factory\FilterFactory; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\PaginatorFactory; | use EasyCorp\Bundle\EasyAdminBundle\Factory\PaginatorFactory; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | ||||
use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | ||||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | use Lc\SovBundle\Doctrine\Extension\TreeInterface; | ||||
use Lc\SovBundle\Field\CollectionField; | use Lc\SovBundle\Field\CollectionField; | ||||
use Lc\SovBundle\Field\Filter\FilterManager; | |||||
use Lc\SovBundle\Form\Common\FiltersFormType; | |||||
use Lc\SovBundle\Form\Common\PositionType; | use Lc\SovBundle\Form\Common\PositionType; | ||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | use Symfony\Component\Form\Extension\Core\Type\CollectionType; | ||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | |||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
use Symfony\Component\HttpFoundation\JsonResponse; | |||||
use Symfony\Component\HttpFoundation\RequestStack; | use Symfony\Component\HttpFoundation\RequestStack; | ||||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | use Symfony\Component\HttpFoundation\Session\SessionInterface; | ||||
abstract class AbstractAdminController extends EaAbstractCrudController | abstract class AbstractAdminController extends EaAbstractCrudController | ||||
{ | { | ||||
protected $filtersForm; | |||||
public static function getSubscribedServices() | public static function getSubscribedServices() | ||||
{ | { | ||||
return array_merge( | return array_merge( | ||||
'request' => RequestStack::class, | 'request' => RequestStack::class, | ||||
'em' => EntityManagerInterface::class, | 'em' => EntityManagerInterface::class, | ||||
'translator_admin' => TranslatorAdmin::class, | 'translator_admin' => TranslatorAdmin::class, | ||||
'filter_manager' => FilterManager::class, | |||||
] | ] | ||||
); | ); | ||||
} | } | ||||
$this->overrideEntitiesActions($responseParameters->get('entities')); | $this->overrideEntitiesActions($responseParameters->get('entities')); | ||||
if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { | if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { | ||||
$responseParameters->set('fields', $this->configureFields('index')); | $responseParameters->set('fields', $this->configureFields('index')); | ||||
if ($this->filtersForm === null) { | |||||
die('nncncd'); | |||||
//TODO delete under code | |||||
$options['fields'] = $responseParameters->get('fields'); | |||||
$options['entity_class'] = $this->getEntityFqcn(); | |||||
$options['entity_name'] = $responseParameters->get('entity')->getName(); | |||||
$this->filtersForm = $this->createForm(FiltersFormType::class, null, $options); | |||||
} | |||||
$responseParameters->set('filters_form', $this->filtersForm); | |||||
} | } | ||||
return $responseParameters; | return $responseParameters; | ||||
} | } | ||||
} | } | ||||
$this->filtersForm = $this->createForm( | |||||
FiltersFormType::class, | |||||
null, | |||||
array( | |||||
'fields' => $fields, | |||||
'entity_dto' => $entityDto, | |||||
'entity_class' => $this->getEntityFqcn(), | |||||
'entity_name' => $entityDto->getName(), | |||||
) | |||||
); | |||||
$filterManager = $this->get('filter_manager'); | |||||
$this->filtersForm->handleRequest($searchDto->getRequest()); | |||||
/*if (($this->filtersForm->isSubmitted() && $this->filtersForm->isValid())) { | |||||
}*/ | |||||
$filterManager->handleFiltersForm($queryBuilder, $this->filtersForm, $fields, $entityDto); | |||||
return $queryBuilder; | return $queryBuilder; | ||||
} | } | ||||
'label' => $this->get('translator_admin')->transAction('delete'), | 'label' => $this->get('translator_admin')->transAction('delete'), | ||||
] | ] | ||||
); | ); | ||||
} | } | ||||
public function buildDetailActions(Actions $actions): void | public function buildDetailActions(Actions $actions): void | ||||
} | } | ||||
} | } | ||||
public function autocompleteFilter(AdminContext $context): JsonResponse | |||||
{ | |||||
$queryBuilder = $this->createIndexQueryBuilder( | |||||
$context->getSearch(), | |||||
$context->getEntity(), | |||||
FieldCollection::new([]), | |||||
FilterCollection::new() | |||||
); | |||||
$autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT); | |||||
/** @var CrudControllerInterface $controller */ | |||||
$controller = $this->get(ControllerFactory::class)->getCrudControllerInstance( | |||||
$autocompleteContext[EA::CRUD_CONTROLLER_FQCN], | |||||
Action::INDEX, | |||||
$context->getRequest() | |||||
); | |||||
/** @var FieldDto $field */ | |||||
$field = FieldCollection::new( | |||||
$controller->configureFields($autocompleteContext['originatingPage']) | |||||
)->getByProperty($autocompleteContext['propertyName']); | |||||
$filterManager = $this->get('filter_manager'); | |||||
$filterManager->applyFilter($queryBuilder, $field, $context->getRequest()->query->get('q')); | |||||
if ($filterManager->isRelationField($field->getProperty())) { | |||||
$queryBuilder->select($autocompleteContext['propertyName']); | |||||
} else { | |||||
$queryBuilder->select('entity.'.$autocompleteContext['propertyName']); | |||||
} | |||||
$responses = array(); | |||||
foreach ($queryBuilder->getQuery()->getArrayResult() as $result) { | |||||
$responses[] = array_values($result)[0]; | |||||
} | |||||
return JsonResponse::fromJsonString(json_encode($responses)); | |||||
} | |||||
} | } | ||||
use Lc\SovBundle\Model\Ticket\TicketInterface; | use Lc\SovBundle\Model\Ticket\TicketInterface; | ||||
use Lc\SovBundle\Controller\AbstractAdminController; | use Lc\SovBundle\Controller\AbstractAdminController; | ||||
use Lc\SovBundle\Model\Ticket\TicketModel; | use Lc\SovBundle\Model\Ticket\TicketModel; | ||||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||||
use Symfony\Component\HttpFoundation\JsonResponse; | use Symfony\Component\HttpFoundation\JsonResponse; | ||||
use Symfony\Component\HttpFoundation\Request; | use Symfony\Component\HttpFoundation\Request; | ||||
protected $ticketMessageFactory; | protected $ticketMessageFactory; | ||||
protected $adminUrlGenerator; | protected $adminUrlGenerator; | ||||
protected $em; | protected $em; | ||||
protected $translatorAdmin; | |||||
public function __construct( | public function __construct( | ||||
TicketFactoryInterface $ticketFactory, | TicketFactoryInterface $ticketFactory, | ||||
TicketMessageFactory $ticketMessageFactory, | TicketMessageFactory $ticketMessageFactory, | ||||
AdminUrlGenerator $adminUrlGenerator | |||||
AdminUrlGenerator $adminUrlGenerator, | |||||
TranslatorAdmin $translatorAdmin | |||||
) { | ) { | ||||
$this->ticketFactory = $ticketFactory; | $this->ticketFactory = $ticketFactory; | ||||
$this->ticketMessageFactory = $ticketMessageFactory; | $this->ticketMessageFactory = $ticketMessageFactory; | ||||
$this->adminUrlGenerator = $adminUrlGenerator; | $this->adminUrlGenerator = $adminUrlGenerator; | ||||
$this->translatorAdmin = $translatorAdmin; | |||||
} | } | ||||
public static function getEntityFqcn(): string | public static function getEntityFqcn(): string | ||||
ChoiceField::new('type') | ChoiceField::new('type') | ||||
->autocomplete() | ->autocomplete() | ||||
->setChoices( | ->setChoices( | ||||
TicketModel::getChoicesType() | |||||
$this->translatorAdmin->transChoices(TicketModel::getTypeChoices(), 'Ticket', 'type') | |||||
), | ), | ||||
ChoiceField::new('status') | ChoiceField::new('status') | ||||
->autocomplete() | ->autocomplete() | ||||
->setChoices( | ->setChoices( | ||||
TicketModel::getChoicesStatus() | |||||
$this->translatorAdmin->transChoices(TicketModel::getStatusChoices(), 'Ticket', 'status') | |||||
) | ) | ||||
->setTemplatePath('@LcSov/admin/ticket/index_status.html.twig') | ->setTemplatePath('@LcSov/admin/ticket/index_status.html.twig') | ||||
->hideOnForm(), | ->hideOnForm(), |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\EntityRepository; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class AssociationFilter | |||||
{ | |||||
use FilterTrait; | |||||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||||
{ | |||||
$targetEntity = $options['entity_dto']->getPropertyMetadata($fieldDto->getProperty())->get('targetEntity'); | |||||
$classImplements = class_implements($targetEntity); | |||||
$builder->add( | |||||
$fieldDto->getProperty(), | |||||
EntityType::class, | |||||
array( | |||||
'class' => $targetEntity, | |||||
'placeholder' => '--', | |||||
'query_builder' => function (EntityRepository $repo) use ($classImplements) { | |||||
return $repo->createQueryBuilder('entity'); | |||||
}, | |||||
'required' => false, | |||||
'attr' => array( | |||||
'class' => 'select2 input-sm', | |||||
'form' => 'filters-form', | |||||
), | |||||
) | |||||
); | |||||
} | |||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue = null) | |||||
{ | |||||
if ($filteredValue !== null) { | |||||
$queryBuilder->andWhere('entity.'.$fieldProperty.' = :'.$fieldProperty.''); | |||||
$queryBuilder->setParameter($fieldProperty, $filteredValue); | |||||
/* //TODO Faut généraliser avec TreeInterface, ça ne doit pas être ici | |||||
if ($field['property'] == 'productCategories') { | |||||
$queryBuilder->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . ' OR product_categories.parent = :' . $field['property']); | |||||
$queryBuilder->setParameter($field['property'], $filter); | |||||
if ($field['type_options']['multiple']) { | |||||
$queryBuilder->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . ''); | |||||
} else { | |||||
} | |||||
if ($filter instanceof TreeInterface && $filter->getParent() == null) { | |||||
$queryBuilder->setParameter($field['property'], array_merge(array($filter), $filter->getChildrens()->toArray())); | |||||
} else { | |||||
}*/ | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
use function Symfony\Component\String\u; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class CheckboxFilter | |||||
{ | |||||
use FilterTrait; | |||||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||||
{ | |||||
$builder->add($fieldDto->getProperty(), ChoiceType::class, array( | |||||
'choices'=> array( | |||||
'Oui' => 1, | |||||
'Non' => 0, | |||||
), | |||||
'placeholder'=> '--', | |||||
'required'=>false, | |||||
'attr'=>array( | |||||
'class'=> 'select2 input-sm', | |||||
'form'=> 'filters-form' | |||||
) | |||||
)); | |||||
} | |||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue= null) | |||||
{ | |||||
if ($filteredValue !== null) { | |||||
if ($this->isRelationField($fieldProperty)) { | |||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty.' = :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
'%'.$filteredValue.'%' | |||||
); | |||||
} else { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||||
} | |||||
dump($queryBuilder); | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
use function Symfony\Component\String\u; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class ChoiceFilter | |||||
{ | |||||
use FilterTrait; | |||||
protected $translatorAdmin; | |||||
public function __construct(?TranslatorAdmin $translatorAdmin = null) | |||||
{ | |||||
$this->translatorAdmin = $translatorAdmin; | |||||
} | |||||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||||
{ | |||||
$entity = new $options['entity_class']; | |||||
$choicesFct = 'get'.u($fieldDto->getProperty())->title()->toString().'Choices'; | |||||
if (method_exists($entity, $choicesFct)) { | |||||
$builder->add( | |||||
$fieldDto->getProperty(), | |||||
ChoiceType::class, | |||||
array( | |||||
'required' => false, | |||||
'choices' => $this->translatorAdmin->transChoices( | |||||
$entity->$choicesFct(), | |||||
$options['entity_name'], | |||||
$fieldDto->getProperty() | |||||
), | |||||
'attr' => array( | |||||
'class' => 'select2 input-sm', | |||||
'form' => 'filters-form', | |||||
), | |||||
) | |||||
); | |||||
} | |||||
} | |||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue = null) | |||||
{ | |||||
if ($filteredValue !== null) { | |||||
if ($this->isRelationField($fieldProperty)) { | |||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
'%'.$filteredValue.'%' | |||||
); | |||||
} else { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' LIKE :'.$fieldProperty.'' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||||
} | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||||
use Symfony\Component\Form\Extension\Core\Type\FormType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class DateFilter | |||||
{ | |||||
use FilterTrait; | |||||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||||
{ | |||||
$builder->add( | |||||
$builder->create( | |||||
str_replace('.', '_', $fieldDto->getProperty()), | |||||
FormType::class, | |||||
array('inherit_data' => true) | |||||
) | |||||
->add( | |||||
'dateStart', | |||||
DateType::class, | |||||
array( | |||||
'widget' => 'single_text', | |||||
'required' => false, | |||||
) | |||||
) | |||||
->add( | |||||
'dateEnd', | |||||
DateType::class, | |||||
array( | |||||
'widget' => 'single_text', | |||||
'required' => false, | |||||
) | |||||
) | |||||
); | |||||
} | |||||
public function applyFilter( | |||||
QueryBuilder $queryBuilder, | |||||
string $fieldProperty, | |||||
\DateTime $dateStart = null, | |||||
\DateTime $dateEnd = null | |||||
) { | |||||
if ($dateStart) { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' >= :dateStart' | |||||
)->setParameter('dateStart', $dateStart); | |||||
} | |||||
if ($dateEnd) { | |||||
$dateEnd->setTime(23, 59, 59); | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' <= :dateEnd' | |||||
)->setParameter('dateEnd', $dateEnd); | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | |||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||||
use Symfony\Component\Form\Form; | |||||
use Symfony\Component\HttpFoundation\RequestStack; | |||||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class FilterManager | |||||
{ | |||||
protected $em; | |||||
use FilterTrait; | |||||
public function __construct(SessionInterface $session, EntityManagerInterface $entityManager) | |||||
{ | |||||
$this->session = $session; | |||||
$this->em = $entityManager; | |||||
} | |||||
public function handleFiltersForm(QueryBuilder $queryBuilder, Form $filtersForm, $fields, EntityDto $entityDto) | |||||
{ | |||||
foreach ($fields as $field) { | |||||
if ($field instanceof FieldInterface) { | |||||
$fieldDto = $field->getAsDto(); | |||||
} else { | |||||
$fieldDto = $field; | |||||
} | |||||
if ($fieldDto->isDisplayedOn(Crud::PAGE_INDEX)) { | |||||
if ($filtersForm->has($this->getFieldPropertySnake($fieldDto->getProperty()))) { | |||||
if ($fieldDto->getFormType() === DateTimeType::class || $fieldDto->getFormType( | |||||
) === DateType::class) { | |||||
$filteredValue['dateStart'] = $this->getFilteredValue( | |||||
$filtersForm, | |||||
$entityDto->getFqcn(), | |||||
$fieldDto->getProperty(), | |||||
'dateStart' | |||||
); | |||||
$filteredValue['dateEnd'] = $this->getFilteredValue( | |||||
$filtersForm, | |||||
$entityDto->getFqcn(), | |||||
$fieldDto->getProperty(), | |||||
'dateEnd' | |||||
); | |||||
}else{ | |||||
$filteredValue = $this->getFilteredValue( | |||||
$filtersForm, | |||||
$entityDto->getFqcn(), | |||||
$fieldDto->getProperty() | |||||
); | |||||
} | |||||
$this->applyFilter($queryBuilder, $fieldDto, $filteredValue); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public function applyFilter(QueryBuilder $queryBuilder, FieldDto $fieldDto, $filteredValue) | |||||
{ | |||||
switch ($fieldDto->getFormType()) { | |||||
case CheckboxType::class: | |||||
$checkboxFilter = new CheckboxFilter(); | |||||
$checkboxFilter->applyFilter($queryBuilder, $fieldDto->getProperty(), $filteredValue); | |||||
break; | |||||
case ChoiceType::class: | |||||
$choiceFilter = new ChoiceFilter(); | |||||
$choiceFilter->applyFilter($queryBuilder, $fieldDto->getProperty(), $filteredValue); | |||||
break; | |||||
case IntegerType::class: | |||||
$integerFilter = new IntegerFilter(); | |||||
$integerFilter->applyFilter($queryBuilder, $fieldDto->getProperty(), $filteredValue); | |||||
break; | |||||
case TextType::class: | |||||
$textFilter = new TextFilter(); | |||||
$textFilter->applyFilter($queryBuilder, $fieldDto->getProperty(), $filteredValue); | |||||
break; | |||||
case EntityType::class: | |||||
$textFilter = new AssociationFilter(); | |||||
$textFilter->applyFilter($queryBuilder, $fieldDto->getProperty(), $filteredValue); | |||||
break; | |||||
case DateTimeType::class: | |||||
case DateType::class: | |||||
$textFilter = new DateFilter(); | |||||
$textFilter->applyFilter( | |||||
$queryBuilder, | |||||
$fieldDto->getProperty(), | |||||
$filteredValue['dateStart'], | |||||
$filteredValue['dateEnd'] | |||||
); | |||||
break; | |||||
} | |||||
} | |||||
public function getFilteredValue( | |||||
Form $filtersForm, | |||||
string $entityFqcn, | |||||
string $field, | |||||
string $dateExtraField = null | |||||
) { | |||||
$field = $this->getFieldPropertySnake($field); | |||||
$sessionParam = $entityFqcn.$field.$dateExtraField; | |||||
$formField = $this->getFormField($filtersForm, $field, $dateExtraField); | |||||
$value = $formField->getData(); | |||||
//Il existe une valeur posté dans le formulaire | |||||
if ($value !== null) { | |||||
$this->session->set($sessionParam, $value); | |||||
return $value; | |||||
} | |||||
//action reset | |||||
if ($filtersForm->get('reset')->getData() == 'clearAll') { | |||||
$this->session->remove($sessionParam); | |||||
return null; | |||||
} | |||||
//Récupération des valeurs stocké en sessions si le forrmFilters n'a pas été posté | |||||
if ($this->session->get($sessionParam) && !$filtersForm->isSubmitted() && $formField) { | |||||
$value = $this->session->get($sessionParam); | |||||
//Champ date | |||||
if ($formField->getConfig()->getOption('input') == 'datetime') { | |||||
$filtersForm->get($field)->get($dateExtraField)->setData($value); | |||||
//Champ association | |||||
} elseif ($formField->getConfig()->getOption('class')) { | |||||
$valFormated = $this->em->getRepository( | |||||
$formField->getConfig()->getOption('class') | |||||
)->find($value); | |||||
$filtersForm->get($field)->setData($valFormated); | |||||
} else { | |||||
//Champ noramux | |||||
$filtersForm->get($field)->setData($value); | |||||
} | |||||
return $value; | |||||
} | |||||
} | |||||
public | |||||
function getFormField( | |||||
Form $filtersForm, | |||||
string $field, | |||||
string $extraField = null | |||||
): Form { | |||||
if ($extraField) { | |||||
return $filtersForm->get($field)->get($extraField); | |||||
} else { | |||||
return $filtersForm->get($field); | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
trait FilterTrait | |||||
{ | |||||
public function getFieldPropertySnake(string $fieldName): string | |||||
{ | |||||
return str_replace('.', '_', $fieldName); | |||||
} | |||||
public function getFieldPropertyBase(string $fieldName): string | |||||
{ | |||||
return str_replace('_', '.', $fieldName); | |||||
} | |||||
public function isRelationField(string $fieldName, string $needle = "."): bool | |||||
{ | |||||
return strpos($fieldName, $needle) !== false; | |||||
} | |||||
public function getFieldPropertyWithoutRelation(string $fieldName, string $needle = '.'): string | |||||
{ | |||||
return substr($fieldName, strpos($fieldName, $needle) + 1); | |||||
} | |||||
public function getFieldPropertyRelationAlias(string $fieldName, string $needle = '.'): string | |||||
{ | |||||
return substr($fieldName, 0, strpos($fieldName, $needle)); | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class IntegerFilter | |||||
{ | |||||
use FilterTrait; | |||||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||||
{ | |||||
$builder->add( | |||||
str_replace('.', '_', $fieldDto->getProperty()), | |||||
IntegerType::class, | |||||
array( | |||||
'required' => false, | |||||
'attr' => array( | |||||
'class' => ' input-sm', | |||||
'form' => 'filters-form', | |||||
), | |||||
) | |||||
); | |||||
} | |||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue= null) | |||||
{ | |||||
if ($filteredValue !== null) { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, $filteredValue); | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Field\Filter; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | |||||
/** | |||||
* @author La clic ! <contact@laclic.fr> | |||||
*/ | |||||
class TextFilter | |||||
{ | |||||
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(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue= null) | |||||
{ | |||||
if ($filteredValue !== null) { | |||||
if ($this->isRelationField($fieldProperty)) { | |||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
'%'.$filteredValue.'%' | |||||
); | |||||
} else { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' LIKE :'.$fieldProperty.'' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||||
} | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\SovBundle\Form\Common; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Doctrine\ORM\EntityRepository; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | |||||
use Lc\SovBundle\Field\Filter\AssociationFilter; | |||||
use Lc\SovBundle\Field\Filter\CheckboxFilter; | |||||
use Lc\SovBundle\Field\Filter\ChoiceFilter; | |||||
use Lc\SovBundle\Field\Filter\DateFilter; | |||||
use Lc\SovBundle\Field\Filter\FilterManager; | |||||
use Lc\SovBundle\Field\Filter\IntegerFilter; | |||||
use Lc\SovBundle\Field\Filter\TextFilter; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||||
use Symfony\Component\Form\AbstractType; | |||||
use Symfony\Component\Form\Extension\Core\Type\ButtonType; | |||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||||
use Symfony\Component\Form\Extension\Core\Type\FormType; | |||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType; | |||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | |||||
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; | |||||
use Symfony\Contracts\Translation\TranslatorInterface; | |||||
use function Symfony\Component\String\u; | |||||
class FiltersFormType extends AbstractType | |||||
{ | |||||
protected $translatorAdmin; | |||||
public function __construct(TranslatorAdmin $translatorAdmin) | |||||
{ | |||||
$this->translatorAdmin = $translatorAdmin; | |||||
} | |||||
public function buildForm(FormBuilderInterface $builder, array $options) | |||||
{ | |||||
foreach ($options['fields'] as $field) { | |||||
if ($field instanceof FieldInterface) { | |||||
$fieldDto = $field->getAsDto(); | |||||
} else { | |||||
$fieldDto = $field; | |||||
} | |||||
if ($fieldDto->isDisplayedOn(Crud::PAGE_INDEX)) { | |||||
switch ($fieldDto->getFormType()) { | |||||
case CheckboxType::class: | |||||
$checkboxFilter = new CheckboxFilter(); | |||||
$checkboxFilter->buildProperty($builder, $fieldDto); | |||||
break; | |||||
case ChoiceType::class: | |||||
$choiceFilter = new ChoiceFilter($this->translatorAdmin); | |||||
$choiceFilter->buildProperty($builder, $fieldDto, $options); | |||||
break; | |||||
case IntegerType::class: | |||||
$integerFilter = new IntegerFilter(); | |||||
$integerFilter->buildProperty($builder, $fieldDto); | |||||
break; | |||||
case TextType::class: | |||||
$textFilter = new TextFilter(); | |||||
$textFilter->buildProperty($builder, $fieldDto); | |||||
break; | |||||
case DateTimeType::class: | |||||
case DateType::class: | |||||
$textFilter = new DateFilter(); | |||||
$textFilter->buildProperty($builder, $fieldDto); | |||||
break; | |||||
case EntityType::class: | |||||
$associationFilter = new AssociationFilter(); | |||||
$associationFilter->buildProperty($builder, $fieldDto, $options); | |||||
break; | |||||
case 'dateinterval': | |||||
break; | |||||
case 'float': | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
$builder->add( | |||||
'action_apply', | |||||
SubmitType::class, | |||||
array( | |||||
'label_html'=> true, | |||||
'label'=> '<i class="fa fa-search"></i>', | |||||
'attr' => array( | |||||
'class' => 'btn btn-sm btn-info', | |||||
'form' => 'filters-form', | |||||
'data-toggle'=>"tooltip", | |||||
'title'=> $this->translatorAdmin->transAction("apply"), | |||||
'aria-label'=> $this->translatorAdmin->transAction("apply") | |||||
), | |||||
) | |||||
); | |||||
$builder->add( | |||||
'action_reset', | |||||
ButtonType::class, | |||||
array( | |||||
'label_html'=> true, | |||||
'label'=> '<i class="fa fa-eraser"></i>', | |||||
'attr' => array( | |||||
'class' => 'btn btn-sm btn-warning lc-reset-filters', | |||||
'form' => 'filters-form', | |||||
'data-toggle'=>"tooltip", | |||||
'title'=> $this->translatorAdmin->transAction("reset"), | |||||
'aria-label'=> $this->translatorAdmin->transAction("reset") | |||||
), | |||||
) | |||||
); | |||||
$builder->add('reset', HiddenType::class); | |||||
} | |||||
public function configureOptions(OptionsResolver $resolver) | |||||
{ | |||||
$resolver->setDefaults( | |||||
[ | |||||
'label' => false, | |||||
'csrf_protection' => false, | |||||
'entity_dto' => null, | |||||
//'translation_domain' => 'lcshop', | |||||
'fields' => false, | |||||
'entity_name' => false, | |||||
'entity_class' => false, | |||||
//'entityClass' => false | |||||
] | |||||
); | |||||
} | |||||
} |
ChoiceType::class, | ChoiceType::class, | ||||
[ | [ | ||||
'label' => 'Type', | 'label' => 'Type', | ||||
'choices' => $this->translatorAdmin->transChoices($entityName::getChoicesType(),TicketInterface::class), | |||||
'choices' => $this->translatorAdmin->transChoices($entityName::getTypeChoices(),'Ticket', 'type'), | |||||
] | ] | ||||
); | ); | ||||
'status', | 'status', | ||||
ChoiceType::class, | ChoiceType::class, | ||||
[ | [ | ||||
'choices' => $this->translatorAdmin->transChoices(TicketModel::getChoicesStatus(),TicketModel::class), | |||||
'choices' => $this->translatorAdmin->transChoices(TicketModel::getStatusChoices(),'Ticket', 'status'), | |||||
'required' => true, | 'required' => true, | ||||
'expanded' => true, | 'expanded' => true, | ||||
'label' => false, | 'label' => false, |
use SortableTrait; | use SortableTrait; | ||||
/** | /** | ||||
* @Gedmo\Translatable | |||||
* @ORM\Column(type="string", length=255, nullable=true) | * @ORM\Column(type="string", length=255, nullable=true) | ||||
*/ | */ | ||||
protected $path; | protected $path; |
const TICKET_STATUS_BEING_PROCESSED = 'being-processed'; | const TICKET_STATUS_BEING_PROCESSED = 'being-processed'; | ||||
const TICKET_STATUS_CLOSED = 'closed'; | const TICKET_STATUS_CLOSED = 'closed'; | ||||
public function getTypeChoices(): array | |||||
{ | |||||
return [ | |||||
TicketModel::TYPE_GENERAL_QUESTION, | |||||
TicketModel::TYPE_TECHNICAL_PROBLEM, | |||||
]; | |||||
} | |||||
public function getStatusChoices(): array | |||||
{ | |||||
return [ | |||||
TicketModel::TICKET_STATUS_OPEN, | |||||
TicketModel::TICKET_STATUS_BEING_PROCESSED, | |||||
TicketModel::TICKET_STATUS_CLOSED, | |||||
]; | |||||
} | |||||
public function getTypeLabel(): string | |||||
{ | |||||
return 'entity.Ticket.fields.typeChoices.'.$this->getType(); | |||||
} | |||||
public function getStatusLabel(): string | |||||
{ | |||||
return 'entity.Ticket.statuChoices.'.$this->getStatus(); | |||||
} | |||||
/** | /** | ||||
* @Gedmo\Blameable(on="create") | * @Gedmo\Blameable(on="create") | ||||
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") | * @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") | ||||
if ($this->getUser()) { | if ($this->getUser()) { | ||||
return $this->getUser()->getName(); | return $this->getUser()->getName(); | ||||
} else { | } else { | ||||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname(); | |||||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname(); | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
$user = $this->getUser(); | $user = $this->getUser(); | ||||
if ($user) { | if ($user) { | ||||
return '#' . $user->getId() . ' ' . $user->getName() . ' ' . $user->getEmail(); | |||||
return '#'.$user->getId().' '.$user->getName().' '.$user->getEmail(); | |||||
} else { | } else { | ||||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname( | |||||
) . ' ' . $this->getVisitorEmail(); | |||||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname().' '.$this->getVisitorEmail( | |||||
); | |||||
} | } | ||||
} | } | ||||
public function getVisitorInfos() | public function getVisitorInfos() | ||||
{ | { | ||||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname( | |||||
) . ' (' . $this->getVisitorEmail() . ')'; | |||||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname().' ('.$this->getVisitorEmail( | |||||
).')'; | |||||
} | } | ||||
public function getLastMessage() | public function getLastMessage() | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getTypeLabel(): string | |||||
{ | |||||
return 'entity.Ticket.fields.typeOptions.' . $this->getType(); | |||||
} | |||||
public function getChoicesType(): array | |||||
{ | |||||
return [ | |||||
'entity.Ticket.fields.typeOptions.' . TicketModel::TYPE_GENERAL_QUESTION => TicketModel::TYPE_GENERAL_QUESTION, | |||||
'entity.Ticket.fields.typeOptions.' . TicketModel::TYPE_TECHNICAL_PROBLEM => TicketModel::TYPE_TECHNICAL_PROBLEM, | |||||
]; | |||||
} | |||||
public function getStatus(): ?string | public function getStatus(): ?string | ||||
{ | { | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getStatusLabel(): string | |||||
{ | |||||
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 | public function getSubject(): ?string | ||||
{ | { |
import 'adminlte-js' ; | import 'adminlte-js' ; | ||||
// Bootstrap | // Bootstrap | ||||
import 'adminlte-plugin/bootstrap/js/bootstrap.min.js'; | |||||
import 'bootstrap/dist/js/bootstrap.min.js'; | |||||
// Bootstrap - autocomplete | |||||
import 'bootstrap-autocomplete'; | |||||
// Select2 | // Select2 | ||||
import 'adminlte-plugin/select2/js/select2.min.js'; | |||||
import 'adminlte-plugin/select2/js/i18n/fr.js'; | |||||
import 'adminlte-plugin/select2/css/select2.min.css'; | |||||
import 'adminlte-plugin/select2-bootstrap4-theme/select2-bootstrap4.min.css'; | |||||
import 'select2/js/select2.min.js'; | |||||
import 'select2/js/i18n/fr.js'; | |||||
import 'select2/css/select2.min.css'; | |||||
import 'select2-bootstrap4-theme'; | |||||
// Toastr | // Toastr | ||||
import toastr from 'toastr/toastr.js' ; | import toastr from 'toastr/toastr.js' ; | ||||
import 'toastr/toastr.scss' ; | import 'toastr/toastr.scss' ; | ||||
global.toastr = toastr ; | global.toastr = toastr ; | ||||
// DaterangePicker | |||||
import 'moment' ; | |||||
import 'daterangepicker/daterangepicker.js' ; | |||||
import 'daterangepicker/daterangepicker.css' ; | |||||
// Tools | // Tools | ||||
import { Tools } from '../../../tools/tools.js'; | import { Tools } from '../../../tools/tools.js'; | ||||
global.Tools = Tools; | global.Tools = Tools; |
/* Notifications */ | /* Notifications */ | ||||
//Notification.init() ; | //Notification.init() ; | ||||
setDateRange(); | |||||
setAutoCompleteField(); | |||||
/* Tooltip */ | /* Tooltip */ | ||||
$('[data-toggle="tooltip"]').tooltip(); | $('[data-toggle="tooltip"]').tooltip(); | ||||
}); | }); | ||||
}); | }); | ||||
function setDateRange(){ | |||||
$('.date-time-range, .date-range').each(function (i, picker) { | |||||
options = { | |||||
autoUpdateInput: false, | |||||
locale: { | |||||
"format": "DD/MM/YY", | |||||
"separator": " - ", | |||||
"applyLabel": "Appliquer", | |||||
"cancelLabel": "Annuler", | |||||
"fromLabel": "Du", | |||||
"toLabel": "au", | |||||
"customRangeLabel": "Custom", | |||||
"daysOfWeek": ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"], | |||||
"monthNames": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], | |||||
"firstDay": 1 | |||||
} | |||||
}; | |||||
if ($(picker).hasClass('date-time-range')){ | |||||
options = Object.assign(options, { | |||||
timePicker: true, | |||||
timePickerIncrement: 30, | |||||
timePicker24Hour: true, | |||||
locale: { | |||||
"format": "DD/MM/YYYY HH:mm", | |||||
} | |||||
}); | |||||
} | |||||
if ($(picker).nextAll('.date-time-range-fields').find('.date-start').val()) { | |||||
options.startDate = new Date($(picker).nextAll('.date-time-range-fields').find('.date-start').val()); | |||||
options.autoUpdateInput = true; | |||||
} | |||||
if ($(picker).nextAll('.date-time-range-fields').find('.date-end').val()) { | |||||
options.endDate = new Date($(picker).nextAll('.date-time-range-fields').find('.date-end').val()); | |||||
options.autoUpdateInput = true; | |||||
} | |||||
$(picker).daterangepicker(options); | |||||
$(picker).on('apply.daterangepicker', function (ev, pickerElm) { | |||||
if ($(picker).hasClass('date-time-range')) { | |||||
$(this).val(pickerElm.startDate.format('DD/MM/YY HH:mm') + ' - ' + pickerElm.endDate.format(options.locale.format)); | |||||
}else{ | |||||
$(this).val(pickerElm.startDate.format('DD/MM/YY') + ' - ' + pickerElm.endDate.format(options.locale.format)); | |||||
} | |||||
if ($(picker).hasClass('date-time-range')) { | |||||
$(picker).nextAll('.date-time-range-fields').find('.date-start').val(pickerElm.startDate.format('YYYY-MM-DD HH:mm')); | |||||
$(picker).nextAll('.date-time-range-fields').find('.date-end').val(pickerElm.endDate.format('YYYY-MM-DD HH:mm')); | |||||
}else{ | |||||
$(picker).nextAll('.date-time-range-fields').find('.date-start').val(pickerElm.startDate.format('YYYY-MM-DD')); | |||||
$(picker).nextAll('.date-time-range-fields').find('.date-end').val(pickerElm.endDate.format('YYYY-MM-DD')); | |||||
} | |||||
}); | |||||
}); | |||||
} | |||||
function setAutoCompleteField() { | |||||
var autocompleteFields = $('[data-lc-autocomplete-url]'); | |||||
autocompleteFields.each(function () { | |||||
var $this = $(this), | |||||
url = $this.data('lc-autocomplete-url'); | |||||
$this.autoComplete({ | |||||
noResultsText: 'Aucun résultat n\'a été trouvé.', | |||||
resolverSettings: { | |||||
url: url | |||||
} | |||||
}); | |||||
}); | |||||
} |
$(document).ready(function() { | $(document).ready(function() { | ||||
lcCrudIndexToggle() ; | lcCrudIndexToggle() ; | ||||
lcCrudIndexBatchActions() ; | lcCrudIndexBatchActions() ; | ||||
lcCrudIndexInitFilter(); | |||||
}) ; | }) ; | ||||
function lcCrudIndexToggle() { | function lcCrudIndexToggle() { | ||||
$form.submit(); | $form.submit(); | ||||
}); | }); | ||||
}); | }); | ||||
} | |||||
function lcCrudIndexInitFilter() { | |||||
$('#filters_form_reset').val(''); | |||||
$('.lc-reset-filters').on('click', function (e) { | |||||
//e.preventDefault(); | |||||
$(this).parents('.table-filters-line').find('select,input').val('').trigger('change'); | |||||
$('#filters_form_reset').val('clearAll'); | |||||
Tools.log($(this).prop('form')); | |||||
$(this).prop('form').submit(); | |||||
//$(this).parents('form').submit(); | |||||
}) | |||||
} | } |
white-space: nowrap; | white-space: nowrap; | ||||
} | } | ||||
} | } | ||||
.table-filters-line th { | |||||
font-weight: 400; | |||||
position: relative; | |||||
} | |||||
.table td, .table th { | |||||
padding: 0.35rem; | |||||
} |
visitorEmail: E-mail | visitorEmail: E-mail | ||||
subject: Sujet | subject: Sujet | ||||
type: Type | type: Type | ||||
typeOptions: | |||||
typeChoices: | |||||
general-question: Questions générales | general-question: Questions générales | ||||
technical-problem: Problème technique | technical-problem: Problème technique | ||||
product-unavailable: Produit manquant | product-unavailable: Produit manquant | ||||
product-error: Erreur sur un produit | product-error: Erreur sur un produit | ||||
lastMessage: Dernier message | lastMessage: Dernier message | ||||
statusOptions: | |||||
statusChoices: | |||||
open: Ouvert | open: Ouvert | ||||
being-processed: En attente | being-processed: En attente | ||||
closed: Fermé | closed: Fermé |
{% set filters_form_are_not_empty = false %} | |||||
{% if filters_form is defined %} | |||||
<tr class="table-filters-line"> | |||||
{% if has_batch_actions %} | |||||
<th></th> | |||||
{% endif %} | |||||
{% for field in fields ?? [] %} | |||||
{% set field = field.getAsDto() %} | |||||
{% if field.isDisplayedOn('index') %} | |||||
<th> | |||||
{% set field_property= field.property|replace({'.': "_"}) %} | |||||
{% if filters_form[field_property] is defined %} | |||||
{% set form_field = filters_form[field_property] %} | |||||
{% if form_field.vars.value is not null and form_field.vars.value is not empty %}{% set filters_form_are_not_empty = true %}{% endif %} | |||||
{% if "DateType" in field.formType or "DateTimeType" in field.formType %} | |||||
<div class="input-group input-group-sm"> | |||||
<input type="text" | |||||
class="form-control input-sm float-right date-range"> | |||||
<div class="hidden date-time-range-fields" | |||||
style="display: none;"> | |||||
{{ form_widget(form_field['dateStart'], {"attr" : {'class' : 'date-start', 'form': 'filters-form'}}) }} | |||||
{{ form_widget(form_field['dateEnd'], {"attr" : {'class' : 'date-end', 'form': 'filters-form'}}) }} | |||||
</div> | |||||
</div> | |||||
{% else %} | |||||
<div class="form-widget input-group-sm"> | |||||
{% set url = ea_url() | |||||
.setController(ea.crudControllers.findCrudFqcnByEntityFqcn(ea.entity.fqcn)) | |||||
.setAction('autocompleteFilter') | |||||
.setEntityId(null) | |||||
.set('page',1) | |||||
.unset('sort') | |||||
.set('autocompleteContext', { | |||||
'crudControllerFqcn': ea.crudControllers.findCrudFqcnByEntityFqcn(ea.entity.fqcn), | |||||
'propertyName': field.property, | |||||
'originatingPage': ea.crud.currentPage, | |||||
}) | |||||
.generateUrl() %} | |||||
{% if 'TextType' in field.formType or 'IntegerType' in field.formType %} | |||||
{{ form_widget(form_field, {'attr': {'autocomplete': 'off', 'data-lc-autocomplete-url' : url}|raw }) }} | |||||
{% else %} | |||||
{{ form_widget(form_field) }} | |||||
{% endif %} | |||||
</div> | |||||
{% endif %} | |||||
{% endif %} | |||||
{% endif %} | |||||
</th> | |||||
{% endfor %} | |||||
<th class="actions"> | |||||
{{ form_widget(filters_form.action_apply) }} | |||||
{% if filters_form_are_not_empty %} | |||||
{{ form_widget(filters_form.action_reset) }} | |||||
{% else %} | |||||
{% do filters_form.action_reset.setRendered %} | |||||
{% endif %} | |||||
</th> | |||||
</tr> | |||||
{% endif %} | |||||
</th> | </th> | ||||
</tr> | </tr> | ||||
{% endblock table_head %} | {% endblock table_head %} | ||||
{% block table_filters %} | |||||
{{ include('@LcSov/adminlte/block/table_filters.html.twig') }} | |||||
{% endblock table_filters %} | |||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
{% endblock table_body %} | {% endblock table_body %} | ||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
{% block filters_form %} | |||||
{% if filters_form is defined %} | |||||
{{ form_start(filters_form, {'attr' :{'id' : 'filters-form'}}) }} | |||||
{#<input type="hidden" name="entity" value="{{ _entity_config.name }}"> | |||||
<input type="hidden" name="menuIndex" value="{{ app.request.get('menuIndex') }}"> | |||||
<input type="hidden" name="submenuIndex" value="{{ app.request.get('submenuIndex') }}"> | |||||
<input type="hidden" name="sortField" value="{{ app.request.get('sortField', '') }}"> | |||||
<input type="hidden" name="sortDirection" | |||||
value="{{ app.request.get('sortDirection', 'DESC') }}"> | |||||
<input type="hidden" name="action" value="{{ app.request.get('action') }}">#} | |||||
{{ form_end(filters_form) }} | |||||
{% endif %} | |||||
{% endblock filters_form %} | |||||
</div> | </div> | ||||
{% endblock %} | {% endblock %} | ||||
{% block footer %} | {% block footer %} | ||||
}); | }); | ||||
});*/ | });*/ | ||||
{% if filters|length > 0 %} | |||||
/* {% if filters|length > 0 %} | |||||
const filterModal = document.querySelector('#modal-filters'); | const filterModal = document.querySelector('#modal-filters'); | ||||
const removeFilter = function (field) { | const removeFilter = function (field) { | ||||
{% if has_batch_actions %} | {% if has_batch_actions %} | ||||
{% endif %} | |||||
{% endif %}*/ | |||||
}); | }); | ||||
</script> | </script> | ||||
); | ); | ||||
} | } | ||||
public function transChoices($choices, $entityClass): array | |||||
public function transChoices(array $choices, string $entityName,string $field): array | |||||
{ | { | ||||
$newChoices = []; | $newChoices = []; | ||||
foreach ($choices as $key => $choice) { | foreach ($choices as $key => $choice) { | ||||
$newChoices[$this->trans($key)] = $choice; | |||||
$newChoices[$this->transField($field.'Choices.'.$choice, $entityName)] = $choice; | |||||
} | } | ||||
return $newChoices; | return $newChoices; |