@@ -3,6 +3,7 @@ | |||
namespace Lc\SovBundle\Container\User; | |||
use Lc\SovBundle\Builder\User\UserBuilder; | |||
use Lc\SovBundle\Definition\Field\User\UserFieldDefinition; | |||
use Lc\SovBundle\Factory\User\UserFactory; | |||
use Lc\SovBundle\Repository\User\UserRepositoryQuery; | |||
use Lc\SovBundle\Repository\User\UserStore; | |||
@@ -15,19 +16,22 @@ class UserContainer | |||
protected UserRepositoryQuery $repositoryQuery; | |||
protected UserStore $store; | |||
protected UserSolver $solver; | |||
protected UserFieldDefinition $fieldDefinition; | |||
public function __construct( | |||
UserFactory $factory, | |||
UserBuilder $builder, | |||
UserRepositoryQuery $repositoryQuery, | |||
UserStore $store, | |||
UserSolver $solver | |||
UserSolver $solver, | |||
UserFieldDefinition $fieldDefinition | |||
) { | |||
$this->factory = $factory; | |||
$this->builder = $builder; | |||
$this->repositoryQuery = $repositoryQuery; | |||
$this->store = $store; | |||
$this->solver = $solver; | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public function getFactory(): UserFactory | |||
@@ -54,4 +58,9 @@ class UserContainer | |||
{ | |||
return $this->solver; | |||
} | |||
public function getFieldDefinition(): UserFieldDefinition | |||
{ | |||
return $this->fieldDefinition; | |||
} | |||
} |
@@ -0,0 +1,82 @@ | |||
<?php | |||
namespace Lc\SovBundle\Definition\Field\User; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use Lc\CaracoleBundle\Field\AssociationField; | |||
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinition; | |||
use Lc\SovBundle\Solver\User\UserSolver; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
class UserFieldDefinition extends AbstractFieldDefinition | |||
{ | |||
protected RolesDefinition $rolesDefinition; | |||
public function __construct(TranslatorAdmin $translatorAdmin, RolesDefinition $rolesDefinition) | |||
{ | |||
parent::__construct($translatorAdmin); | |||
$this->rolesDefinition = $rolesDefinition; | |||
} | |||
public function configureFieldsIndex(): array | |||
{ | |||
return [ | |||
'id', | |||
'gender', | |||
'lastname', | |||
'firstname', | |||
'email', | |||
'groupUsers' | |||
]; | |||
} | |||
public function configureFieldsForm(): array | |||
{ | |||
return [ | |||
'id', | |||
'gender', | |||
'lastname', | |||
'firstname', | |||
'email', | |||
'phone', | |||
'birthdate', | |||
'groupUsers' | |||
]; | |||
} | |||
public function configurePanels(): array | |||
{ | |||
return []; | |||
} | |||
public function configureFields(): array | |||
{ | |||
return [ | |||
'id' => IntegerField::new('id')->onlyOnIndex()->setSortable(true), | |||
'gender' => ChoiceField::new('gender')->setChoices( | |||
$this->translatorAdmin->transChoices(UserSolver::getGenderChoices(), 'User', 'gender') | |||
) | |||
->setFormTypeOption('expanded', true) | |||
->setFormTypeOption('multiple', false) | |||
->setSortable(true), | |||
'lastname' => TextField::new('lastname')->setSortable(true), | |||
'firstname' => TextField::new('firstname')->setSortable(true), | |||
'email' => TextField::new('email')->setSortable(true), | |||
'phone' => TextField::new('phone')->setSortable(true), | |||
'birthdate' => DateField::new('birthdate')->setSortable(true), | |||
'groupUsers' => AssociationField::new('groupUsers')->setSortable(true), | |||
'roles' => ChoiceField::new('roles') | |||
->allowMultipleChoices() | |||
->autocomplete() | |||
->setChoices($this->rolesDefinition->getRolesList()), | |||
]; | |||
} | |||
} |
@@ -18,30 +18,38 @@ class AssociationFilter | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$param = array(); | |||
$targetEntity = $options['entity_dto']->getPropertyMetadata($fieldDto->getProperty())->get('targetEntity'); | |||
if($fieldDto->getCustomOption('choices')){ | |||
if ($fieldDto->getCustomOption('choices')) { | |||
$choices = $fieldDto->getCustomOption('choices'); | |||
}else if($fieldDto->getFormTypeOption('choices') !=null){ | |||
} elseif ($fieldDto->getFormTypeOption('choices') != null) { | |||
$choices = $fieldDto->getFormTypeOption('choices'); | |||
}else{ | |||
} else { | |||
$choices = array(); | |||
} | |||
if ($fieldDto->getFormTypeOption('choice_label') != null) { | |||
$param['choice_label'] = $fieldDto->getFormTypeOption('choice_label'); | |||
} | |||
//todo utiliser choices plutot que query_builder voir ProductCategoriesFilter | |||
$builder->add( | |||
$fieldDto->getProperty(), | |||
EntityType::class, | |||
array( | |||
'class' => $targetEntity, | |||
'placeholder' => '--', | |||
'choices' => $choices, | |||
'required' => false, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', | |||
'form' => 'filters-form', | |||
), | |||
array_merge( | |||
$param, | |||
array( | |||
'class' => $targetEntity, | |||
'placeholder' => '--', | |||
'choices' => $choices, | |||
'required' => false, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
) | |||
); | |||
} | |||
@@ -49,7 +57,7 @@ class AssociationFilter | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, $filteredValue = null) | |||
{ | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->andWhere('.'.$fieldProperty.' = :'.$fieldProperty.''); | |||
$repositoryQuery->andWhere('.' . $fieldProperty . ' = :' . $fieldProperty . ''); | |||
$repositoryQuery->setParameter($fieldProperty, $filteredValue); | |||
/* //TODO Faut généraliser avec TreeInterface, ça ne doit pas être ici | |||
if ($field['type_options']['multiple']) { |
@@ -50,6 +50,7 @@ abstract class UserModel implements EntityInterface, UserInterface, DevAliasInte | |||
* @ORM\Column(type="string", length=20, nullable=true) | |||
*/ | |||
protected $phone; | |||
/** | |||
* @ORM\Column(type="boolean", nullable=true) | |||
*/ |
@@ -100,6 +100,13 @@ abstract class AbstractStore implements StoreInterface | |||
return $query->find(); | |||
} | |||
public function getAll($query = null) | |||
{ | |||
$query = $this->createQuery($query); | |||
$query->filterIsOnlineAndOffline(); | |||
return $query->find(); | |||
} | |||
public function getOnline($query = null) | |||
{ | |||
$query = $this->createDefaultQuery($query); |
@@ -4,99 +4,5 @@ import "./form.scss" | |||
$(document).ready(function () { | |||
initCollectionWidget(); | |||
SovWidgets.setCollectionWidget(); | |||
}); | |||
function initCollectionWidget() { | |||
$('.field-collection[data-prototype]').each(function (i, collectionWidget) { | |||
setCollectionWidgetSortable($(collectionWidget)); | |||
reindexKeyCollectionWidget($(collectionWidget)); | |||
setCollectionWidgetAdd($(collectionWidget)); | |||
setCollectionWidgetDelete($(collectionWidget)); | |||
}); | |||
} | |||
function setCollectionWidgetAdd($collectionWidget) { | |||
if ($collectionWidget.data('allow-add')) { | |||
$collectionWidget.find('.field-collection-add').on('click', function (e) { | |||
// grab the prototype template | |||
var newWidget = $collectionWidget.attr('data-prototype'); | |||
// replace the "__name__" used in the id and name of the prototype | |||
// with a number that's unique to your emails | |||
// end name attribute looks like name="contact[emails][2]" | |||
newWidget = newWidget.replace(/__name__/g, getNumItems($collectionWidget)); | |||
// create a new list element and add it to the list | |||
$collectionWidget.find('.form-widget-compound .field-collection-group').append(newWidget); | |||
$collectionWidget.find('.field-collection-item:last').find('.field-position').val(getNumItems($collectionWidget)); | |||
reindexKeyCollectionWidget($collectionWidget); | |||
setCollectionWidgetDelete($collectionWidget); | |||
$collectionWidget.trigger('collection-add-item'); | |||
$collectionWidget.data('num-items', $collectionWidget.data('num-items') + 1); | |||
$collectionWidget.find('.collection-empty').hide(); | |||
}); | |||
} | |||
} | |||
function setCollectionWidgetDelete($collectionWidget) { | |||
if ($collectionWidget.data('allow-delete')) { | |||
$collectionWidget.find('.field-collection-delete').off('click'); | |||
$collectionWidget.find('.field-collection-delete').on('click', function () { | |||
$(this).parents('.form-group:first').remove(); | |||
reindexKeyCollectionWidget($collectionWidget); | |||
if(getNumItems($collectionWidget)==0)$collectionWidget.find('.collection-empty').show(); | |||
}); | |||
} | |||
} | |||
function getNumItems($collectionWidget) { | |||
if ($collectionWidget.data('reindex-key')) { | |||
return $collectionWidget.find('.field-collection-item').length; | |||
} else { | |||
return $collectionWidget.data('num-items'); | |||
} | |||
} | |||
function reindexKeyCollectionWidget($collectionWidget) { | |||
if ($collectionWidget.data('reindex-key')) { | |||
$collectionWidget.find('.field-collection-item').each(function (i, item) { | |||
$(item).find('input,textarea').each(function (y, field) { | |||
let $field = $(field); | |||
//Chanegment ID | |||
let posIdPrefix = parseInt(SovTools.indexOfFirstDigit($field.prop('id'))); | |||
let posIdSuffix = parseInt(SovTools.indexOfLastDigit($field.prop('id'))); | |||
let idPrefix = $field.prop('id').substr(0, posIdPrefix); | |||
let idSuffix = $field.prop('id').substr(posIdSuffix + 1); | |||
$field.prop('id', idPrefix + i + idSuffix); | |||
//Chanegment Name | |||
let posNamePrefix = SovTools.indexOfFirstDigit($field.prop('name')); | |||
let posNameSuffix = SovTools.indexOfLastDigit($field.prop('name')); | |||
let namePrefix = $field.prop('name').substr(0, posNamePrefix); | |||
let nameSuffix = $field.prop('name').substr(posNameSuffix + 1); | |||
$field.prop('name', namePrefix + i + nameSuffix); | |||
}); | |||
}); | |||
} | |||
} | |||
function setCollectionWidgetSortable($collectionWidget) { | |||
if ($collectionWidget.data('sortable')) { | |||
$collectionWidget.find('.field-collection-group').sortable({ | |||
"handle" : '.lc-btn-sortable', | |||
cancel: '' | |||
}); | |||
$collectionWidget.find('.field-collection-group').on("sortupdate", function (event, ui) { | |||
$collectionWidget.find('.field-collection-group>div').each(function (index, item) { | |||
$(item).find('.field-position').val(index); | |||
}); | |||
}); | |||
} | |||
} |
@@ -37,6 +37,10 @@ global.SovTools = SovTools; | |||
import { SovPrices } from '../../../functions/prices.js'; | |||
global.SovPrices = SovPrices; | |||
// Widgets | |||
import { SovWidgetCollection } from '../../../functions/widget-collection.js'; | |||
global.SovWidgetCollection = SovWidgetCollection; | |||
// Widgets | |||
import { SovWidgets } from '../../../functions/widgets.js'; | |||
global.SovWidgets = SovWidgets; |
@@ -0,0 +1,84 @@ | |||
export class SovWidgetCollection { | |||
static setCollectionWidgetAdd($collectionWidget) { | |||
if ($collectionWidget.data('allow-add')) { | |||
$collectionWidget.find('.field-collection-add').on('click', function (e) { | |||
// grab the prototype template | |||
var newWidget = $collectionWidget.attr('data-prototype'); | |||
// replace the "__name__" used in the id and name of the prototype | |||
// with a number that's unique to your emails | |||
// end name attribute looks like name="contact[emails][2]" | |||
newWidget = newWidget.replace(/__name__/g, SovWidgetCollection.getNumItems($collectionWidget)); | |||
// create a new list element and add it to the list | |||
$collectionWidget.find('.form-widget-compound .field-collection-group').append(newWidget); | |||
$collectionWidget.find('.field-collection-item:last').find('.field-position').val(SovWidgetCollection.getNumItems($collectionWidget)); | |||
SovWidgetCollection.reindexKeyCollectionWidget($collectionWidget); | |||
SovWidgetCollection.setCollectionWidgetDelete($collectionWidget); | |||
$collectionWidget.trigger('collection-add-item'); | |||
$collectionWidget.data('num-items', $collectionWidget.data('num-items') + 1); | |||
$collectionWidget.find('.collection-empty').hide(); | |||
}); | |||
} | |||
} | |||
static setCollectionWidgetDelete($collectionWidget) { | |||
if ($collectionWidget.data('allow-delete')) { | |||
$collectionWidget.find('.field-collection-delete').off('click'); | |||
$collectionWidget.find('.field-collection-delete').on('click', function () { | |||
$(this).parents('.form-group:first').remove(); | |||
SovWidgetCollection.reindexKeyCollectionWidget($collectionWidget); | |||
if (getNumItems($collectionWidget) == 0) $collectionWidget.find('.collection-empty').show(); | |||
}); | |||
} | |||
} | |||
static getNumItems($collectionWidget) { | |||
if ($collectionWidget.data('reindex-key')) { | |||
return $collectionWidget.find('.field-collection-item').length; | |||
} else { | |||
return $collectionWidget.data('num-items'); | |||
} | |||
} | |||
static reindexKeyCollectionWidget($collectionWidget) { | |||
if ($collectionWidget.data('reindex-key')) { | |||
$collectionWidget.find('.field-collection-item').each(function (i, item) { | |||
$(item).find('input,textarea').each(function (y, field) { | |||
let $field = $(field); | |||
//Chanegment ID | |||
let posIdPrefix = parseInt(SovTools.indexOfFirstDigit($field.prop('id'))); | |||
let posIdSuffix = parseInt(SovTools.indexOfLastDigit($field.prop('id'))); | |||
let idPrefix = $field.prop('id').substr(0, posIdPrefix); | |||
let idSuffix = $field.prop('id').substr(posIdSuffix + 1); | |||
$field.prop('id', idPrefix + i + idSuffix); | |||
//Chanegment Name | |||
let posNamePrefix = SovTools.indexOfFirstDigit($field.prop('name')); | |||
let posNameSuffix = SovTools.indexOfLastDigit($field.prop('name')); | |||
let namePrefix = $field.prop('name').substr(0, posNamePrefix); | |||
let nameSuffix = $field.prop('name').substr(posNameSuffix + 1); | |||
$field.prop('name', namePrefix + i + nameSuffix); | |||
}); | |||
}); | |||
} | |||
} | |||
static setCollectionWidgetSortable($collectionWidget) { | |||
if ($collectionWidget.data('sortable')) { | |||
$collectionWidget.find('.field-collection-group').sortable({ | |||
"handle": '.lc-btn-sortable', | |||
cancel: '' | |||
}); | |||
$collectionWidget.find('.field-collection-group').on("sortupdate", function (event, ui) { | |||
$collectionWidget.find('.field-collection-group>div').each(function (index, item) { | |||
$(item).find('.field-position').val(index); | |||
}); | |||
}); | |||
} | |||
} | |||
} |
@@ -105,4 +105,16 @@ export class SovWidgets { | |||
}); | |||
}); | |||
} | |||
static setCollectionWidget() { | |||
$('.field-collection[data-prototype]').each(function (i, collectionWidget) { | |||
SovWidgetCollection.setCollectionWidgetSortable($(collectionWidget)); | |||
SovWidgetCollection.reindexKeyCollectionWidget($(collectionWidget)); | |||
SovWidgetCollection.setCollectionWidgetAdd($(collectionWidget)); | |||
SovWidgetCollection.setCollectionWidgetDelete($(collectionWidget)); | |||
}); | |||
} | |||
} |
@@ -51,6 +51,12 @@ entity: | |||
fields: | |||
firstname: Prénom | |||
lastname: Nom | |||
gender: Sexe | |||
genderChoices: | |||
0: Homme | |||
1: Femme | |||
birthdate: Date de naissance | |||
groupUsers: Groupe d'utilisateurs | |||
Page: | |||
label: Page | |||
label_plurial: Pages |
@@ -77,6 +77,7 @@ | |||
{% block main %} | |||
<div class="row"> | |||
<div class="col-8"> | |||
{% block form %} | |||
{{ form(form) }} | |||
@@ -105,6 +106,7 @@ | |||
{{ include('@EasyAdmin/crud/includes/_delete_form.html.twig', { entity_id: entity.primaryKeyValue }, with_context = false) }} | |||
{% endif %} | |||
{% endblock delete_form %} | |||
</div> | |||
{% endblock %} | |||
@@ -5,6 +5,7 @@ namespace Lc\SovBundle\Solver\User; | |||
use Lc\SovBundle\Model\Newsletter\NewsletterInterface; | |||
use Lc\SovBundle\Model\User\GroupUserInterface; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Model\User\UserModel; | |||
class UserSolver | |||
{ | |||
@@ -62,4 +63,11 @@ class UserSolver | |||
} | |||
} | |||
public static function getGenderChoices(){ | |||
return[ | |||
'0', | |||
'1' | |||
]; | |||
} | |||
} |