@@ -12,9 +12,12 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; | |||
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\Dto\EntityDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | |||
@@ -22,9 +25,11 @@ use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException; | |||
use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException; | |||
use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory; | |||
use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory; | |||
use EasyCorp\Bundle\EasyAdminBundle\Factory\FilterFactory; | |||
use EasyCorp\Bundle\EasyAdminBundle\Factory\PaginatorFactory; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
@@ -36,16 +41,25 @@ use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||
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\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\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\HttpFoundation\JsonResponse; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
protected $filtersForm; | |||
public static function getSubscribedServices() | |||
{ | |||
return array_merge( | |||
@@ -55,6 +69,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
'request' => RequestStack::class, | |||
'em' => EntityManagerInterface::class, | |||
'translator_admin' => TranslatorAdmin::class, | |||
'filter_manager' => FilterManager::class, | |||
] | |||
); | |||
} | |||
@@ -66,6 +81,16 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$this->overrideEntitiesActions($responseParameters->get('entities')); | |||
if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { | |||
$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; | |||
@@ -291,6 +316,25 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
} | |||
$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; | |||
} | |||
@@ -489,9 +533,6 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
); | |||
} | |||
public function buildDetailActions(Actions $actions): void | |||
@@ -628,6 +669,45 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
} | |||
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)); | |||
} | |||
} | |||
@@ -21,6 +21,7 @@ use Lc\SovBundle\Form\Ticket\TicketStatusType; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Controller\AbstractAdminController; | |||
use Lc\SovBundle\Model\Ticket\TicketModel; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use Symfony\Component\HttpFoundation\Request; | |||
@@ -30,15 +31,18 @@ class TicketAdminController extends AbstractAdminController | |||
protected $ticketMessageFactory; | |||
protected $adminUrlGenerator; | |||
protected $em; | |||
protected $translatorAdmin; | |||
public function __construct( | |||
TicketFactoryInterface $ticketFactory, | |||
TicketMessageFactoryInterface $ticketMessageFactory, | |||
AdminUrlGenerator $adminUrlGenerator | |||
AdminUrlGenerator $adminUrlGenerator, | |||
TranslatorAdmin $translatorAdmin | |||
) { | |||
$this->ticketFactory = $ticketFactory; | |||
$this->ticketMessageFactory = $ticketMessageFactory; | |||
$this->adminUrlGenerator = $adminUrlGenerator; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public static function getEntityFqcn(): string | |||
@@ -77,12 +81,13 @@ class TicketAdminController extends AbstractAdminController | |||
ChoiceField::new('type') | |||
->autocomplete() | |||
->setChoices( | |||
TicketModel::getChoicesType() | |||
$this->translatorAdmin->transChoices(TicketModel::getTypeChoices(), 'Ticket', 'type') | |||
), | |||
ChoiceField::new('status') | |||
->autocomplete() | |||
->setChoices( | |||
TicketModel::getChoicesStatus() | |||
$this->translatorAdmin->transChoices(TicketModel::getStatusChoices(), 'Ticket', 'status') | |||
) | |||
->setTemplatePath('@LcSov/admin/ticket/field/status.html.twig') | |||
->hideOnForm(), |
@@ -0,0 +1,67 @@ | |||
<?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 { | |||
}*/ | |||
} | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
<?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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,77 @@ | |||
<?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.'%'); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,64 @@ | |||
<?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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,175 @@ | |||
<?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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
<?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)); | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
<?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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
<?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.'%'); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,140 @@ | |||
<?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 | |||
] | |||
); | |||
} | |||
} |
@@ -49,7 +49,7 @@ class TicketFormType extends AbstractType | |||
ChoiceType::class, | |||
[ | |||
'label' => 'Type', | |||
'choices' => $this->translatorAdmin->transChoices($entityName::getChoicesType(),TicketInterface::class), | |||
'choices' => $this->translatorAdmin->transChoices($entityName::getTypeChoices(),'Ticket', 'type'), | |||
] | |||
); | |||
@@ -29,7 +29,7 @@ class TicketStatusType extends AbstractType | |||
'status', | |||
ChoiceType::class, | |||
[ | |||
'choices' => $this->translatorAdmin->transChoices(TicketModel::getChoicesStatus(),TicketModel::class), | |||
'choices' => $this->translatorAdmin->transChoices(TicketModel::getStatusChoices(),'Ticket', 'status'), | |||
'required' => true, | |||
'expanded' => true, | |||
'label' => false, |
@@ -26,6 +26,7 @@ abstract class FileModel implements SortableInterface, BlameableInterface, Times | |||
use SortableTrait; | |||
/** | |||
* @Gedmo\Translatable | |||
* @ORM\Column(type="string", length=255, nullable=true) | |||
*/ | |||
protected $path; |
@@ -0,0 +1,33 @@ | |||
<?php | |||
namespace Lc\SovBundle\Model\Setting; | |||
trait EntitySettingTrait | |||
{ | |||
public function getSetting($name) | |||
{ | |||
if ($this->getSettings()) { | |||
foreach ($this->getSettings() as $setting) { | |||
if ($setting->getName() == $name) { | |||
return $setting; | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
public function getSettingValue($name) | |||
{ | |||
if ($this->getSettings()) { | |||
foreach ($this->getSettings() as $setting) { | |||
if ($setting->getName() == $name) { | |||
return $setting->getValue(); | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
} |
@@ -22,6 +22,35 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
const TICKET_STATUS_BEING_PROCESSED = 'being-processed'; | |||
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") | |||
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") | |||
@@ -97,7 +126,7 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
if ($this->getUser()) { | |||
return $this->getUser()->getName(); | |||
} else { | |||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname(); | |||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname(); | |||
} | |||
} | |||
@@ -105,10 +134,10 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
{ | |||
$user = $this->getUser(); | |||
if ($user) { | |||
return '#' . $user->getId() . ' ' . $user->getName() . ' ' . $user->getEmail(); | |||
return '#'.$user->getId().' '.$user->getName().' '.$user->getEmail(); | |||
} else { | |||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname( | |||
) . ' ' . $this->getVisitorEmail(); | |||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname().' '.$this->getVisitorEmail( | |||
); | |||
} | |||
} | |||
@@ -123,8 +152,8 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
public function getVisitorInfos() | |||
{ | |||
return strtoupper($this->getVisitorLastname()) . ' ' . $this->getVisitorFirstname( | |||
) . ' (' . $this->getVisitorEmail() . ')'; | |||
return strtoupper($this->getVisitorLastname()).' '.$this->getVisitorFirstname().' ('.$this->getVisitorEmail( | |||
).')'; | |||
} | |||
public function getLastMessage() | |||
@@ -144,18 +173,6 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
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 | |||
{ | |||
@@ -169,19 +186,6 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
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 | |||
{ |
@@ -7,19 +7,28 @@ global.$ = global.jQuery = $; | |||
import 'adminlte-js' ; | |||
// Bootstrap | |||
import 'adminlte-plugin/bootstrap/js/bootstrap.min.js'; | |||
import 'bootstrap/dist/js/bootstrap.min.js'; | |||
// Bootstrap - autocomplete | |||
import 'bootstrap-autocomplete'; | |||
// 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 | |||
import toastr from 'toastr/toastr.js' ; | |||
import 'toastr/toastr.scss' ; | |||
global.toastr = toastr ; | |||
// DaterangePicker | |||
import 'moment' ; | |||
import 'daterangepicker/daterangepicker.js' ; | |||
import 'daterangepicker/daterangepicker.css' ; | |||
// Tools | |||
import { Tools } from '../../../tools/tools.js'; | |||
global.Tools = Tools; |
@@ -2,6 +2,12 @@ | |||
/* Notifications */ | |||
//Notification.init() ; | |||
setDateRange(); | |||
setAutoCompleteField(); | |||
/* Tooltip */ | |||
$('[data-toggle="tooltip"]').tooltip(); | |||
@@ -74,3 +80,76 @@ $('.action-delete').on('click', function (e) { | |||
}); | |||
}); | |||
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 | |||
} | |||
}); | |||
}); | |||
} |
@@ -3,6 +3,7 @@ | |||
$(document).ready(function() { | |||
lcCrudIndexToggle() ; | |||
lcCrudIndexBatchActions() ; | |||
lcCrudIndexInitFilter(); | |||
}) ; | |||
function lcCrudIndexToggle() { | |||
@@ -132,4 +133,18 @@ function lcCrudIndexBatchActions() { | |||
$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(); | |||
}) | |||
} |
@@ -6,3 +6,12 @@ table.table { | |||
white-space: nowrap; | |||
} | |||
} | |||
.table-filters-line th { | |||
font-weight: 400; | |||
position: relative; | |||
} | |||
.table td, .table th { | |||
padding: 0.35rem; | |||
} |
@@ -76,13 +76,13 @@ entity: | |||
visitorEmail: E-mail | |||
subject: Sujet | |||
type: Type | |||
typeOptions: | |||
typeChoices: | |||
general-question: Questions générales | |||
technical-problem: Problème technique | |||
product-unavailable: Produit manquant | |||
product-error: Erreur sur un produit | |||
lastMessage: Dernier message | |||
statusOptions: | |||
statusChoices: | |||
open: Ouvert | |||
being-processed: En attente | |||
closed: Fermé |
@@ -0,0 +1,67 @@ | |||
{% 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 %} | |||
@@ -103,6 +103,11 @@ | |||
</th> | |||
</tr> | |||
{% endblock table_head %} | |||
{% block table_filters %} | |||
{{ include('@LcSov/adminlte/block/table_filters.html.twig') }} | |||
{% endblock table_filters %} | |||
</thead> | |||
<tbody> | |||
@@ -177,6 +182,22 @@ | |||
{% endblock table_body %} | |||
</tbody> | |||
</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> | |||
{% endblock %} | |||
{% block footer %} | |||
@@ -222,7 +243,7 @@ | |||
}); | |||
});*/ | |||
{% if filters|length > 0 %} | |||
/* {% if filters|length > 0 %} | |||
const filterModal = document.querySelector('#modal-filters'); | |||
const removeFilter = function (field) { | |||
@@ -283,7 +304,7 @@ | |||
{% if has_batch_actions %} | |||
{% endif %} | |||
{% endif %}*/ | |||
}); | |||
</script> | |||
@@ -39,11 +39,11 @@ class TranslatorAdmin | |||
); | |||
} | |||
public function transChoices($choices, $entityClass): array | |||
public function transChoices(array $choices, string $entityName,string $field): array | |||
{ | |||
$newChoices = []; | |||
foreach ($choices as $key => $choice) { | |||
$newChoices[$this->trans($key)] = $choice; | |||
$newChoices[$this->transField($field.'Choices.'.$choice, $entityName)] = $choice; | |||
} | |||
return $newChoices; |