@@ -40,6 +40,7 @@ use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||
use Lc\SovBundle\Field\CollectionField; | |||
use Lc\SovBundle\Field\GalleryManagerField; | |||
use Lc\SovBundle\Form\Type\Crud\PositionType; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
@@ -51,13 +52,21 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
{ | |||
protected $session; | |||
protected $request; | |||
public function __construct(SessionInterface $session, RequestStack $request, EntityManager $em, Environment $twig) | |||
protected $translatorAdmin; | |||
public function __construct( | |||
SessionInterface $session, | |||
RequestStack $request, | |||
EntityManager $em, | |||
Environment $twig, | |||
TranslatorAdmin $translatorAdmin | |||
) | |||
{ | |||
$this->session = $session; | |||
$this->request = $request; | |||
$this->em = $em; | |||
$this->twig = $twig; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function configureActions(Actions $actions): Actions | |||
@@ -65,68 +74,78 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
/* Translatable */ | |||
if ($this->isInstanceOf(TranslatableInterface::class)) { | |||
$actions->update( | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
function (Action $action) { | |||
$action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig'); | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
function (Action $action) { | |||
$action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig'); | |||
return $action; | |||
} | |||
return $action; | |||
} | |||
); | |||
} | |||
/* Boutons des actions dans les listes */ | |||
$actionsArray[Crud::PAGE_INDEX] = [ | |||
Action::NEW => [ | |||
'icon' => 'plus', | |||
'label' => 'Créer', | |||
'add_class' => 'btn-sm' | |||
], | |||
Action::EDIT => [ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
'html_attributes' => array('data-toggle' => 'tooltip', 'title' => 'Éditer') | |||
], | |||
Action::DELETE => [ | |||
'icon' => 'trash', | |||
'dropdown' => true, | |||
], | |||
Action::BATCH_DELETE => [ | |||
'class' => 'btn btn-sm btn-danger', | |||
'icon' => 'trash', | |||
], | |||
Action::NEW => [ | |||
'icon' => 'plus', | |||
'label' => $this->translatorAdmin->transAction('create'), | |||
'add_class' => 'btn-sm' | |||
], | |||
Action::EDIT => [ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
'html_attributes' => array( | |||
'data-toggle' => 'tooltip', | |||
'title' => $this->translatorAdmin->transAction('edit') | |||
) | |||
], | |||
Action::DELETE => [ | |||
'icon' => 'trash', | |||
'dropdown' => true, | |||
'label' => $this->translatorAdmin->transAction('delete') | |||
], | |||
Action::BATCH_DELETE => [ | |||
'class' => 'btn btn-sm btn-danger', | |||
'icon' => 'trash', | |||
'label' => $this->translatorAdmin->transAction('delete') | |||
], | |||
]; | |||
/* Boutons des actions dans l'édition */ | |||
$actionSaveAndReturn = [ | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'label' => $this->translatorAdmin->transAction('save_and_return') | |||
]; | |||
$actionIndex = [ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'label' => $this->translatorAdmin->transAction('back_index') | |||
]; | |||
$actionsArray[Crud::PAGE_EDIT] = [ | |||
Action::SAVE_AND_CONTINUE => [ | |||
'class' => 'btn btn-info float-right', | |||
], | |||
Action::DELETE => [ | |||
'icon' => 'trash', | |||
'class' => 'btn btn-outline-danger action-delete', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX => $actionIndex, | |||
Action::SAVE_AND_CONTINUE => [ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->translatorAdmin->transAction('save_and_continue') | |||
], | |||
Action::DELETE => [ | |||
'icon' => 'trash', | |||
'class' => 'btn btn-outline-danger action-delete', | |||
'label' => $this->translatorAdmin->transAction('delete') | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX => $actionIndex, | |||
]; | |||
$actionsArray[Crud::PAGE_NEW] = [ | |||
Action::SAVE_AND_ADD_ANOTHER => [ | |||
'class' => 'btn btn-info float-right', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX => $actionIndex, | |||
Action::SAVE_AND_ADD_ANOTHER => [ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->translatorAdmin->transAction('save_and_add_another') | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX => $actionIndex, | |||
]; | |||
$actions->add(Crud::PAGE_EDIT, Action::INDEX); | |||
@@ -134,27 +153,35 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$actions->add(Crud::PAGE_NEW, Action::INDEX); | |||
if ($this->isInstanceOf(SortableInterface::class)) { | |||
$sortAction = Action::new('sort', 'Ordonner', 'fa fa-sort') | |||
->linkToCrudAction('sort') | |||
->setCssClass('btn btn-sm btn-success') | |||
->createAsGlobalAction(); | |||
$sortAction = Action::new('sort', $this->translatorAdmin->transAction('sort'), 'fa fa-sort') | |||
->linkToCrudAction('sort') | |||
->setCssClass('btn btn-sm btn-success') | |||
->createAsGlobalAction(); | |||
$actions->add(Crud::PAGE_INDEX, $sortAction); | |||
} | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
$indexChildAction = Action::new('index_children', 'Afficher les enfants', 'fa fa-list') | |||
->linkToCrudAction(Action::INDEX) | |||
->setLabel('') | |||
->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants')) | |||
->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig') | |||
->setCssClass('btn btn-sm btn-success'); | |||
$backParentAction = Action::new('index_parent', 'Retour au parent', 'fa fa-chevron-left') | |||
->linkToCrudAction(Action::INDEX) | |||
->setCssClass('btn btn-sm btn-info') | |||
->createAsGlobalAction(); | |||
$indexChildAction = Action::new( | |||
'index_children', | |||
$this->translatorAdmin->transAction('index_children'), | |||
'fa fa-list' | |||
) | |||
->linkToCrudAction(Action::INDEX) | |||
->setLabel('') | |||
->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants')) | |||
->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig') | |||
->setCssClass('btn btn-sm btn-success'); | |||
$backParentAction = Action::new( | |||
'index_parent', | |||
$this->translatorAdmin->transAction('index_parent'), | |||
'fa fa-chevron-left' | |||
) | |||
->linkToCrudAction(Action::INDEX) | |||
->setCssClass('btn btn-sm btn-info') | |||
->createAsGlobalAction(); | |||
$actions->add(Crud::PAGE_INDEX, $backParentAction); | |||
$actions->add(Crud::PAGE_INDEX, $indexChildAction); | |||
@@ -167,35 +194,35 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
foreach ($actionsArray as $crudActionName => $actionsStyle) { | |||
foreach ($actionsStyle as $actionName => $button) { | |||
$actions->update( | |||
$crudActionName, | |||
$actionName, | |||
function (Action $action) use ($button) { | |||
if (isset($button['add_class'])) { | |||
$action->addCssClass($button['add_class']); | |||
} | |||
if (isset($button['class'])) { | |||
$action->setCssClass($button['class']); | |||
} | |||
if (isset($button['icon'])) { | |||
$action->setIcon('fa fa-' . $button['icon']); | |||
} | |||
if (isset($button['label'])) { | |||
$action->setLabel($button['label']); | |||
} | |||
if (isset($button['dropdown']) && $button['dropdown']) { | |||
$action->addCssClass('in-dropdown'); | |||
} | |||
if (isset($button['html_attributes']) && $button['html_attributes']) { | |||
$action->setHtmlAttributes($button['html_attributes']); | |||
} | |||
return $action; | |||
$crudActionName, | |||
$actionName, | |||
function (Action $action) use ($button) { | |||
if (isset($button['add_class'])) { | |||
$action->addCssClass($button['add_class']); | |||
} | |||
if (isset($button['class'])) { | |||
$action->setCssClass($button['class']); | |||
} | |||
if (isset($button['icon'])) { | |||
$action->setIcon('fa fa-' . $button['icon']); | |||
} | |||
if (isset($button['label'])) { | |||
$action->setLabel($button['label']); | |||
} | |||
if (isset($button['dropdown']) && $button['dropdown']) { | |||
$action->addCssClass('in-dropdown'); | |||
} | |||
if (isset($button['html_attributes']) && $button['html_attributes']) { | |||
$action->setHtmlAttributes($button['html_attributes']); | |||
} | |||
return $action; | |||
} | |||
); | |||
} | |||
} | |||
@@ -235,7 +262,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$this->session->set($paramSessionListMaxResults, $requestListMaxResults); | |||
} | |||
$maxResults = $this->session->get($paramSessionListMaxResults) ? $this->session->get( | |||
$paramSessionListMaxResults | |||
$paramSessionListMaxResults | |||
) : 30; | |||
$crud->setPaginatorPageSize($maxResults); | |||
@@ -243,26 +270,28 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
public function configureFields(string $pageName): iterable | |||
{ | |||
$seoPanel = $confPanel = array(); | |||
if ($this->isInstanceOf(SortableInterface::class)) { | |||
$seoPanel = [ | |||
FormField::addPanel('seo'), | |||
TextField::new('metaTitle')->setLabel('Meta Title')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
FormField::addPanel('seo')->setTemplateName('crud/field/generic'), | |||
TextField::new('metaTitle')->setLabel('Meta Title')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
CollectionField::new('oldUrls') | |||
->setFormTypeOption('entry_type', TextType::class)->setLabel( | |||
'Anciennes urls du document' | |||
)->hideOnIndex(), | |||
CollectionField::new('oldUrls') | |||
->setFormTypeOption('entry_type', TextType::class)->setLabel( | |||
'Anciennes urls du document' | |||
)->hideOnIndex(), | |||
]; | |||
} | |||
if ($this->isInstanceOf(DevAliasInterface::class)) { | |||
$confPanel = [ | |||
FormField::addPanel('configuration'), | |||
TextField::new('devAlias')->hideOnIndex(), | |||
FormField::addPanel('configuration')->setTemplateName('crud/field/generic'), | |||
TextField::new('devAlias')->hideOnIndex(), | |||
]; | |||
} | |||
@@ -284,9 +313,9 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX)); | |||
$filters = $this->get(FilterFactory::class)->create( | |||
$context->getCrud()->getFiltersConfig(), | |||
$fields, | |||
$context->getEntity() | |||
$context->getCrud()->getFiltersConfig(), | |||
$fields, | |||
$context->getEntity() | |||
); | |||
$queryBuilder = $this->createIndexQueryBuilder($context->getSearch(), $context->getEntity(), $fields, $filters); | |||
$paginator = $this->get(PaginatorFactory::class)->create($queryBuilder); | |||
@@ -295,16 +324,16 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$this->get(EntityFactory::class)->processFieldsForAll($entities, $fields); | |||
$sortableForm = $this->createFormBuilder(array('entities', $paginator->getResults())) | |||
->add( | |||
'entities', | |||
CollectionType::class, | |||
array( | |||
'required' => true, | |||
'allow_add' => true, | |||
'entry_type' => PositionType::class, | |||
) | |||
->add( | |||
'entities', | |||
CollectionType::class, | |||
array( | |||
'required' => true, | |||
'allow_add' => true, | |||
'entry_type' => PositionType::class, | |||
) | |||
->getForm(); | |||
) | |||
->getForm(); | |||
$entityManager = $this->getDoctrine()->getManagerForClass($this->getEntityFqcn()); | |||
$repository = $entityManager->getRepository($this->getEntityFqcn()); | |||
@@ -331,26 +360,26 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
} | |||
$url = $this->get(AdminUrlGenerator::class) | |||
->setAction(Action::INDEX) | |||
->generateUrl(); | |||
$this->addFlash('success', 'Position modifié', array()); | |||
->setAction(Action::INDEX) | |||
->generateUrl(); | |||
$this->addFlash('success', $this->translatorAdmin->transFlashMessage('sort'), array()); | |||
return $this->redirect($url); | |||
} | |||
$responseParameters = $this->configureResponseParameters( | |||
KeyValueStore::new( | |||
[ | |||
'pageName' => Crud::PAGE_INDEX, | |||
'templatePath' => '@LcSov/adminlte/crud/sort.html.twig', | |||
'entities' => $entities, | |||
'paginator' => $paginator, | |||
'global_actions' => array(), | |||
'batch_actions' => array(), | |||
'filters' => $filters, | |||
'sortable_form' => $sortableForm, | |||
] | |||
) | |||
KeyValueStore::new( | |||
[ | |||
'pageName' => Crud::PAGE_INDEX, | |||
'templatePath' => '@LcSov/adminlte/crud/sort.html.twig', | |||
'entities' => $entities, | |||
'paginator' => $paginator, | |||
'global_actions' => array(), | |||
'batch_actions' => array(), | |||
'filters' => $filters, | |||
'sortable_form' => $sortableForm, | |||
] | |||
) | |||
); | |||
$responseParameters->set('fields', $this->configureFields('index')); | |||
$event = new AfterCrudActionEvent($context, $responseParameters); | |||
@@ -363,16 +392,17 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
} | |||
public function createIndexQueryBuilder( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder | |||
{ | |||
$queryBuilder = parent::createIndexQueryBuilder( | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
); | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
@@ -390,16 +420,17 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
} | |||
public function createSortQueryBuilder( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder | |||
{ | |||
$queryBuilder = parent::createIndexQueryBuilder( | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
); | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
@@ -418,14 +449,14 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
public function edit(AdminContext $context) | |||
{ | |||
$response = parent::edit($context); ; | |||
$response = parent::edit($context);; | |||
// on vide le flash bag si édition en ajax (notification déjà affichée en Javascript) | |||
if ($context->getRequest()->isXmlHttpRequest()) { | |||
$this->session->getFlashBag()->clear() ; | |||
$this->session->getFlashBag()->clear(); | |||
} | |||
return $response ; | |||
return $response; | |||
} | |||
public function isInstanceOf(string $interfaceName): bool |
@@ -23,14 +23,14 @@ class DashboardController extends AbstractDashboardController | |||
public function configureDashboard(): Dashboard | |||
{ | |||
return Dashboard::new() | |||
// the name visible to end users | |||
->setTitle('LA CLIC !') | |||
// you can include HTML contents too (e.g. to link to an image) | |||
->setTitle('<img src="assets/img/laclic.png" width="100px">') | |||
// the path defined in this method is passed to the Twig asset() function | |||
->setFaviconPath('favicon.svg') | |||
// the domain used by default is 'messages' | |||
->setTranslationDomain('admin'); | |||
// the name visible to end users | |||
->setTitle('LA CLIC !') | |||
// you can include HTML contents too (e.g. to link to an image) | |||
->setTitle('<img src="assets/img/laclic.png" width="100px">') | |||
// the path defined in this method is passed to the Twig asset() function | |||
->setFaviconPath('favicon.svg') | |||
// the domain used by default is 'messages' | |||
->setTranslationDomain('admin'); | |||
} | |||
public function configureAssets(): Assets | |||
@@ -41,6 +41,8 @@ class DashboardController extends AbstractDashboardController | |||
$assets->addWebpackEncoreEntry('adminlte-index'); | |||
$assets->addWebpackEncoreEntry('adminlte-form'); | |||
$assets->addWebpackEncoreEntry('adminlte-sort'); | |||
$assets->addWebpackEncoreEntry('adminlte-field-collection'); | |||
$assets->addWebpackEncoreEntry('adminlte-field-filemanager'); | |||
return $assets; | |||
} | |||
@@ -51,22 +53,22 @@ class DashboardController extends AbstractDashboardController | |||
// user menu with some menu items already created ("sign out", "exit impersonation", etc.) | |||
// if you prefer to create the user menu from scratch, use: return UserMenu::new()->... | |||
return parent::configureUserMenu($user) | |||
// use the given $user object to get the user name | |||
->setName($user->getName()) | |||
// use this method if you don't want to display the name of the user | |||
//->displayUserName(false) | |||
->displayUserAvatar(false) | |||
// you can also pass an email address to use gravatar's service | |||
->setGravatarEmail($user->getEmail()) | |||
// use the given $user object to get the user name | |||
->setName($user->getName()) | |||
// use this method if you don't want to display the name of the user | |||
//->displayUserName(false) | |||
->displayUserAvatar(false) | |||
// you can also pass an email address to use gravatar's service | |||
->setGravatarEmail($user->getEmail()) | |||
// you can use any type of menu item, except submenus | |||
->setMenuItems( | |||
[ | |||
//MenuItem::linkToRoute('My Profile', 'fa fa-id-card', '', ['...' => '...']), | |||
MenuItem::linkToLogout('Déconnexion', 'sign-out-alt'), | |||
//MenuItem::linkToLogout('Déconnexion', 'sign-out-alt') | |||
] | |||
); | |||
// you can use any type of menu item, except submenus | |||
->setMenuItems( | |||
[ | |||
//MenuItem::linkToRoute('My Profile', 'fa fa-id-card', '', ['...' => '...']), | |||
MenuItem::linkToLogout('Déconnexion', 'sign-out-alt'), | |||
//MenuItem::linkToLogout('Déconnexion', 'sign-out-alt') | |||
] | |||
); | |||
} | |||
public function configureCrud(): Crud | |||
@@ -74,24 +76,23 @@ class DashboardController extends AbstractDashboardController | |||
$crud = Crud::new(); | |||
return $crud | |||
->overrideTemplates( | |||
[ | |||
'layout' => '@LcSov/adminlte/layout.html.twig', | |||
'main_menu' => '@LcSov/adminlte/block/menu.html.twig', | |||
'crud/index' => '@LcSov/adminlte/crud/index.html.twig', | |||
'crud/paginator' => '@LcSov/adminlte/crud/paginator.html.twig', | |||
'crud/edit' => '@LcSov/adminlte/crud/edit.html.twig', | |||
'crud/new' => '@LcSov/adminlte/crud/new.html.twig', | |||
'flash_messages' => '@LcSov/adminlte/block/flash_messages.html.twig', | |||
] | |||
) | |||
->setFormThemes( | |||
[ | |||
'@LcSov/adminlte/crud/form_theme.html.twig', | |||
'@FOSCKEditor/Form/ckeditor_widget.html.twig' | |||
] | |||
) | |||
; | |||
->overrideTemplates( | |||
[ | |||
'layout' => '@LcSov/adminlte/layout.html.twig', | |||
'main_menu' => '@LcSov/adminlte/block/menu.html.twig', | |||
'crud/index' => '@LcSov/adminlte/crud/index.html.twig', | |||
'crud/paginator' => '@LcSov/adminlte/crud/paginator.html.twig', | |||
'crud/edit' => '@LcSov/adminlte/crud/edit.html.twig', | |||
'crud/new' => '@LcSov/adminlte/crud/new.html.twig', | |||
'flash_messages' => '@LcSov/adminlte/block/flash_messages.html.twig', | |||
] | |||
) | |||
->setFormThemes( | |||
[ | |||
'@LcSov/adminlte/crud/form_theme.html.twig', | |||
'@FOSCKEditor/Form/ckeditor_widget.html.twig' | |||
] | |||
); | |||
} | |||
} |
@@ -12,6 +12,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
use Symfony\Component\HttpFoundation\Request; | |||
use Symfony\Component\HttpFoundation\Response; | |||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; | |||
use Symfony\Component\Translation\TranslatableMessage; | |||
class UserController extends AbstractController | |||
{ | |||
@@ -34,6 +35,8 @@ class UserController extends AbstractController | |||
$this->em->update($user); | |||
$this->em->flush(); | |||
$this->addFlash('success', new TranslatableMessage('form.account_profile.message.success', [], 'admin')); | |||
} | |||
return $this->render( | |||
@@ -62,6 +65,8 @@ class UserController extends AbstractController | |||
$this->em->update($user); | |||
$this->em->flush(); | |||
$this->addFlash('success', new TranslatableMessage('form.account_password.message.success', [], 'admin')); | |||
} | |||
return $this->render( |
@@ -26,7 +26,7 @@ class CollectionField implements FieldInterface | |||
->setLabel($label) | |||
->setTemplatePath('@LcSov/adminlte/crud/field/collection.html.twig') | |||
->setFormType(CollectionType::class) | |||
->addWebpackEncoreEntries('adminlte-field-collection') | |||
/*->addWebpackEncoreEntries('adminlte-field-collection')*/ | |||
->setFormTypeOption('allow_add', true) | |||
->setFormTypeOption('allow_delete', true) | |||
->setFormTypeOption('entry_options', array('label' => false)) |
@@ -23,7 +23,9 @@ final class FileManagerField implements FieldInterface | |||
->setProperty($propertyName) | |||
->setLabel($label) | |||
->setTemplatePath('@LcSov/adminlte/crud/field/file.html.twig') | |||
->addWebpackEncoreEntries('adminlte-field-filemanager') | |||
/*->addWebpackEncoreEntries('adminlte-field-filemanager')*/ | |||
->setCustomOption('managerDir', 'file') | |||
->setCustomOption('type', 'file') | |||
->setFormType(FileManagerType::class) | |||
->addCssClass('field-text') | |||
->setCustomOption(self::OPTION_MAX_LENGTH, null) |
@@ -26,8 +26,8 @@ class GalleryManagerField implements FieldInterface | |||
->setTemplatePath('@LcSov/adminlte/crud/field/collection.html.twig') | |||
->setFormType(CollectionType::class) | |||
->addCssClass('field-collection') | |||
->addWebpackEncoreEntries('adminlte-field-collection') | |||
->addWebpackEncoreEntries('adminlte-field-filemanager') | |||
/*->addWebpackEncoreEntries('adminlte-field-collection') | |||
->addWebpackEncoreEntries('adminlte-field-filemanager')*/ | |||
->setFormTypeOption('allow_add', true) | |||
->setFormTypeOption('allow_delete', true) | |||
->setFormTypeOption('entry_options', array('label'=> false)) |
@@ -25,6 +25,8 @@ final class ImageManagerField implements FieldInterface | |||
->setTemplatePath('@LcSov/adminlte/crud/field/image.html.twig') | |||
->addWebpackEncoreEntries('adminlte-field-filemanager') | |||
->setFormType(FileManagerType::class) | |||
->setCustomOption('managerDir', 'image') | |||
->setCustomOption('type', 'image') | |||
->addCssClass('field-text') | |||
->setCustomOption(self::OPTION_MAX_LENGTH, null) | |||
->setCustomOption(self::OPTION_RENDER_AS_HTML, false); |
@@ -13,6 +13,7 @@ namespace Lc\SovBundle\Form\Type\User; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\PasswordType; | |||
use Symfony\Component\Form\Extension\Core\Type\RepeatedType; | |||
@@ -26,11 +27,13 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
class ChangePasswordFormType extends AbstractType | |||
{ | |||
protected $em ; | |||
protected $em; | |||
protected $translatorAdmin; | |||
public function __construct(EntityManager $em) | |||
public function __construct(EntityManager $em, TranslatorAdmin $translatorAdmin) | |||
{ | |||
$this->em = $em ; | |||
$this->em = $em; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
/** | |||
@@ -50,7 +53,7 @@ class ChangePasswordFormType extends AbstractType | |||
'current_password', | |||
PasswordType::class, | |||
[ | |||
'label' => 'form.change_password.current_password', | |||
'label' => 'form.account_password.field.current_password', | |||
'mapped' => false, | |||
'constraints' => [ | |||
new NotBlank(), | |||
@@ -60,14 +63,14 @@ class ChangePasswordFormType extends AbstractType | |||
); | |||
$builder->add( | |||
'plainPassword', | |||
'plain_password', | |||
RepeatedType::class, | |||
[ | |||
'type' => PasswordType::class, | |||
'mapped' => false, | |||
'first_options' => ['label' => 'form.change_password.new_password'], | |||
'second_options' => ['label' => 'form.change_password.new_password_repeat'], | |||
'invalid_message' => 'Les deux mots de passe ne correspondent pas.', | |||
'first_options' => ['label' => 'form.account_password.field.new_password'], | |||
'second_options' => ['label' => 'form.account_password.field.new_password_repeat'], | |||
'invalid_message' => $this->translatorAdmin->trans('form.account_password.message.invalid_passwords'), | |||
] | |||
); | |||
@@ -75,7 +78,7 @@ class ChangePasswordFormType extends AbstractType | |||
'submit', | |||
SubmitType::class, | |||
array( | |||
'label' => new TranslatableMessage('action.save', [], 'admin') | |||
'label' => $this->translatorAdmin->transAction('save') | |||
) | |||
); | |||
} |
@@ -6,6 +6,7 @@ use Lc\SovBundle\DataTransformer\FileManagerTypeToDataTransformer; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\EmailType; | |||
use Symfony\Component\Form\Extension\Core\Type\SubmitType; | |||
@@ -17,10 +18,12 @@ use Symfony\Component\Translation\TranslatableMessage; | |||
class ProfileFormType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $translatorAdmin; | |||
public function __construct(EntityManager $em) | |||
public function __construct(EntityManager $em, TranslatorAdmin $translatorAdmin) | |||
{ | |||
$this->em = $em; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
@@ -53,7 +56,7 @@ class ProfileFormType extends AbstractType | |||
'submit', | |||
SubmitType::class, | |||
[ | |||
'label' => new TranslatableMessage('action.save', [], 'admin') | |||
'label' => $this->translatorAdmin->transAction('save') | |||
] | |||
); | |||
} |
@@ -15,6 +15,7 @@ function initFileManager() { | |||
let $field = $(this); | |||
$('#' + $field.data('id')).val(""); | |||
$('#' + $field.data('id') + '_preview').prop('src',""); | |||
$('#' + $field.data('id') + '_preview_text').html('Aucun fichier'); | |||
}); | |||
$('.lc-filemanager-open').off('click'); | |||
$('.lc-filemanager-open').on('click', function (e) { | |||
@@ -25,6 +26,7 @@ function initFileManager() { | |||
var path = $(this).attr('data-path') | |||
$('#' + $field.data('id')).val(path); | |||
$('#' + $field.data('id') + '_preview').prop('src',path); | |||
$('#' + $field.data('id') + '_preview_text').html(path); | |||
$('#lc-filemanager-modal').modal('hide'); | |||
}); | |||
}); |
@@ -1,20 +1,12 @@ | |||
flash_message: | |||
create: Le contenu "%name%" a été créé avec succès. | |||
update: Le contenu "%name%" a été mis à jour avec succès. | |||
delete: Le contenu "%name%" a été supprimé avec succès. | |||
menu: | |||
dashboard: Tableau de bord | |||
page: Pages | |||
user: | |||
label: Utilisateurs | |||
childs: | |||
index: Liste | |||
account: | |||
label: Mon compte | |||
childs: | |||
profile: Informations personnelles | |||
password: Mot de passe | |||
user: Utilisateurs | |||
user_index: Liste | |||
account: Mon compte | |||
account_profile: Informations personnelles | |||
account_password: Mot de passe | |||
title: | |||
dashboard: Tableau de bord | |||
@@ -27,14 +19,33 @@ title: | |||
profile: Mes informations personnelles | |||
change_password: Changer de mot de passe | |||
action: | |||
create: Créer | |||
edit: Éditer | |||
save: Sauvegarder | |||
sort: Ordonner | |||
delete: Supprimer | |||
index_children: Afficher les enfants | |||
index_parent: Retour au parent | |||
back_index: Retour à la liste | |||
save_and_return: Sauvegarder les modifications | |||
save_and_continue: Sauvegarder et continuer l'édition | |||
save_and_add_another: Créer et ajouter un nouvel élément | |||
flash_message: | |||
create: Le contenu "%name%" a été créé avec succès. | |||
update: Le contenu "%name%" a été mis à jour avec succès. | |||
delete: Le contenu "%name%" a été supprimé avec succès. | |||
sort: Position modifiée | |||
entity: | |||
user: | |||
User: | |||
label: Utilisateur | |||
label_plurial: Utilisateurs | |||
fields: | |||
firstname: Prénom | |||
lastname: Nom | |||
page: | |||
Page: | |||
label: Page | |||
label_plurial: Pages | |||
default: | |||
@@ -47,17 +58,29 @@ entity: | |||
file: Fichier | |||
status: Statut | |||
email: Email | |||
metaTitle: Meta title | |||
metaTitle_help: Affiché dans les résultats de recherche Google | |||
metaDescription: Meta description | |||
metaDescription_help: Affiché dans les résultats de recherche Google | |||
oldUrls: Anciennes urls | |||
devAlias: Alias | |||
gallery: Galerie | |||
panels: | |||
general: Général | |||
configuration: Configuration | |||
gallery: Galerie | |||
seo: Référencement | |||
action: | |||
save: Sauvegarder | |||
form: | |||
change_password: | |||
current_password: Mot de passe actuel | |||
new_password: Nouveau mot de passe | |||
new_password_repeat: Nouveau mot de passe (confirmer) | |||
account_profile: | |||
message: | |||
success: Votre profil a bien été modifié | |||
account_password: | |||
field: | |||
current_password: Mot de passe actuel | |||
new_password: Nouveau mot de passe | |||
new_password_repeat: Nouveau mot de passe (confirmer) | |||
message: | |||
success: Votre mot de passe a bien été modifié | |||
invalid_passwords: Les deux mots de passe ne correspondent pas. |
@@ -13,11 +13,12 @@ | |||
{% block configured_stylesheets %} | |||
{{ parent() }} | |||
{% for css_asset in form.vars.ea_crud_form.assets.cssFiles %} | |||
{% for css_asset in form.vars.ea_crud_form.assets.cssAssets %} | |||
<link rel="stylesheet" href="{{ asset(css_asset) }}"> | |||
{% endfor %} | |||
{% for webpack_encore_entry in form.vars.ea_crud_form.assets.webpackEncoreEntries %} | |||
{% for webpack_encore_entry in form.vars.ea_crud_form.assets.webpackEncoreAssets %} | |||
{{ ea_call_function_if_exists('encore_entry_link_tags', webpack_encore_entry) }} | |||
{% endfor %} | |||
{% endblock %} | |||
@@ -25,11 +26,12 @@ | |||
{% block configured_javascripts %} | |||
{{ parent() }} | |||
{% for js_asset in form.vars.ea_crud_form.assets.jsFiles %} | |||
{% for js_asset in form.vars.ea_crud_form.assets.jsAssets %} | |||
<script src="{{ asset(js_asset) }}"></script> | |||
{% endfor %} | |||
{% for webpack_encore_entry in form.vars.ea_crud_form.assets.webpackEncoreEntries %} | |||
{% for webpack_encore_entry in form.vars.ea_crud_form.assets.webpackEncoreAssets %} | |||
{{ ea_call_function_if_exists('encore_entry_script_tags', webpack_encore_entry) }} | |||
{% endfor %} | |||
{% endblock %} |
@@ -6,16 +6,17 @@ | |||
{% for _locale in app_locales %} | |||
<a class="{{ isIncludedInDropdown|default(false) ? 'dropdown-item' }} {{ action.cssClass }}" | |||
href="{{ action.linkUrl }}&_locale={{ _locale }}" | |||
{% for name, value in action.htmlAttributes %}{{ name }}="{{ value|e('html_attr') }}" {% endfor %}> | |||
{%- if action.icon %}<i class="action-icon {{ action.icon }}"></i> {% endif -%} | |||
{%- if action.label is not empty -%}{{ action.label }} {{ _locale }}{%- endif -%} | |||
{% for name, value in action.htmlAttributes %}{{ name }}="{{ value|e('html_attr') }}" {% endfor %}> | |||
{%- if action.icon %}<i class="action-icon {{ action.icon }}"></i> {% endif -%} | |||
{%- if action.label is not empty -%}{{ action.label }} {%- endif -%} | |||
{{ _locale }} | |||
</a> | |||
{% endfor %} | |||
{% elseif 'button' == action.htmlElement %} | |||
<button class="{{ action.cssClass }}" {% for name, value in action.htmlAttributes %}{{ name }}="{{ value|e('html_attr') }}" {% endfor %}> | |||
<span class="btn-label"> | |||
<span class="btn-label"> | |||
{%- if action.icon %}<i class="action-icon {{ action.icon }}"></i> {% endif -%} | |||
{%- if action.label is not empty -%}{{ action.label }}{%- endif -%} | |||
{%- if action.label is not empty -%}{{ action.label }}{%- endif -%} | |||
</span> | |||
</button> | |||
{% endif %} |
@@ -13,7 +13,8 @@ | |||
{% set has_append_html = ea.field.append_html|default(null) is not null %} | |||
{% set has_input_groups = has_prepend_html or has_append_html %} | |||
{% if has_input_groups %}<div class="input-group">{% endif %} | |||
{% if has_input_groups %} | |||
<div class="input-group">{% endif %} | |||
{% if has_prepend_html %} | |||
<div class="input-group-prepend"> | |||
<span class="input-group-text">{{ ea.field.prepend_html|raw }}</span> | |||
@@ -38,7 +39,7 @@ | |||
<div class="nullable-control"> | |||
<label> | |||
<input type="checkbox" {% if data is null %}checked="checked"{% endif %}> | |||
{{ 'label.nullable_field'|trans({}, 'EasyAdminBundle')}} | |||
{{ 'label.nullable_field'|trans({}, 'EasyAdminBundle') }} | |||
</label> | |||
</div> | |||
{% endif %} | |||
@@ -147,15 +148,29 @@ | |||
{% block file_manager_widget %} | |||
<div class="lc-filemanager row"> | |||
<div class="col-md-3 col-xs-12 form-group"> | |||
{% if form.vars.ea_crud_form.ea_field is not null %} | |||
{% set managerDir = form.vars.ea_crud_form.ea_field.customOptions.get('managerDir') %} | |||
{% set type = form.vars.ea_crud_form.ea_field.customOptions.get('type') %} | |||
<div class="lc-filemanager row"> | |||
{% if type == 'image' %} | |||
<div class="col-md-3 col-xs-12 form-group"> | |||
<div class="lc-filemenager-preview card"> | |||
<div class="no-image"> | |||
<i class="fa fa-image"></i> | |||
</div> | |||
<img src="{{ form.path.vars.value }}" id="{{ form.path.vars.id }}_preview" alt="" class="card-img-top"> | |||
</div> | |||
</div> | |||
</div> | |||
{% else %} | |||
<div class="callout callout-success"> | |||
<h5><i class="fa fa-file-alt"></i> | |||
<span id="{{ form.path.vars.id }}_preview_text">{{ form.path.vars.value }}</span> | |||
</h5> | |||
</div> | |||
{% endif %} | |||
<div class="col-12"> | |||
<div class="input-group"> | |||
<div class="input-group-prepend"> | |||
@@ -167,7 +182,7 @@ | |||
{% endif %} | |||
<button type="button" class="btn btn-primary lc-filemanager-open" data-id="{{ form.path.vars.id }}" | |||
data-toggle="tooltip" title="Sélectionner un fichier" | |||
data-target="{{ path('file_manager', {module:1, conf:'default'})|raw }}"> | |||
data-target="{{ path('file_manager', {module:1, conf: managerDir})|raw }}"> | |||
<i class="fa fa-folder-open"></i> | |||
</button> | |||
</div> | |||
@@ -184,11 +199,12 @@ | |||
{{ form_rest(form) }} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{% endif %} | |||
{% endblock file_manager_widget %} | |||
{% block checkbox_radio_label -%} | |||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#} | |||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#} | |||
{%- if widget is defined -%} | |||
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class or 'switch-custom' in parent_label_class) %} | |||
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class or 'switch-custom' in label_attr.class) %} | |||
@@ -245,10 +261,11 @@ | |||
{% for panel_name, panel_config in ea_crud_form.form_panels|filter(panel_config => not panel_config.form_tab or panel_config.form_tab == tab_name) %} | |||
{% set panel_has_header = panel_config.label|default(false) or panel_config.icon|default(false) %} | |||
<li class="nav-item"> | |||
<a href="#panel-{{ panel_name }} " class="nav-link {{ panel_name == 1 ? 'active' }}" data-toggle="tab" role="tab" | |||
<a href="#panel-{{ panel_name }} " class="nav-link {{ panel_name == 1 ? 'active' }}" | |||
data-toggle="tab" role="tab" | |||
aria-controls="panel-{{ panel_name }}"> | |||
{{ panel_config.label|lc_trans_admin_panel(ea.getEntity().getFqcn()) }} | |||
<i class="fa fa-exclamation-circle invalid-form"></i> | |||
<i class="fa fa-exclamation-circle invalid-form"></i> | |||
</a> | |||
</li> | |||
{% endfor %} |
@@ -27,7 +27,8 @@ | |||
<link rel="stylesheet" href="{{ asset(css_asset) }}"> | |||
{% endfor %} | |||
{% for webpack_encore_entry in ea.assets.webpackEncoreEntries ?? [] %} | |||
{% for webpack_encore_entry in ea.assets.webpackEncoreAssets ?? [] %} | |||
{{ ea_call_function_if_exists('encore_entry_link_tags', webpack_encore_entry) }} | |||
{% endfor %} | |||
{% endblock %} | |||
@@ -55,6 +56,7 @@ | |||
{% block body %} | |||
<body id="{% block body_id %}{% endblock %}" class="sidebar-mini layout-fixed {% block body_class %}{% endblock %}"> | |||
{% block javascript_page_layout %} | |||
<script> | |||
document.body.classList.add( | |||
@@ -164,7 +166,7 @@ | |||
<script src="{{ asset(js_asset) }}"></script> | |||
{% endfor %} | |||
{% for webpack_encore_entry in ea.assets.webpackEncoreEntries ?? [] %} | |||
{% for webpack_encore_entry in ea.assets.webpackEncoreAssets ?? [] %} | |||
{{ ea_call_function_if_exists('encore_entry_script_tags', webpack_encore_entry, null, '_default', {'defer': false}) }} | |||
{% endfor %} | |||
{% endblock %} |
@@ -16,6 +16,21 @@ class TranslatorAdmin | |||
$this->translator = $translator; | |||
} | |||
public function transAction($action) | |||
{ | |||
return $this->trans('action.' . $action); | |||
} | |||
public function transMenu($menu) | |||
{ | |||
return $this->trans('menu.' . $menu); | |||
} | |||
public function transFlashMessage($name) | |||
{ | |||
return $this->trans('flash_message.' . $name); | |||
} | |||
public function transField($fieldName, $entityClass): string | |||
{ | |||
return $this->transEntityThenDefault( | |||
@@ -47,14 +62,14 @@ class TranslatorAdmin | |||
{ | |||
$entityName = $this->getEntityName($entityClass); | |||
$paramsTranslation = [] ; | |||
$paramsTranslation = []; | |||
if($entityName) { | |||
$baseIdEntityLabel = 'entity.' . $entityName ; | |||
if ($entityName) { | |||
$baseIdEntityLabel = 'entity.' . $entityName; | |||
$paramsTranslation = [ | |||
'%label%' => $this->trans($baseIdEntityLabel . '.label'), | |||
'%label_plurial%' => $this->trans($baseIdEntityLabel . '.label_plurial'), | |||
] ; | |||
]; | |||
} | |||
if (isset($params['id'])) { | |||
@@ -88,16 +103,15 @@ class TranslatorAdmin | |||
private function buildTransIdField($fieldName, $entityClass, $default = false): string | |||
{ | |||
if ($default) { | |||
$entityName = 'default'; | |||
} else { | |||
$entityName = $this->getEntityName($entityClass); | |||
} | |||
return 'entity.' . $entityName . '.fields.' . $fieldName; | |||
return $this->buildTransIdEntitySection($fieldName, $entityClass, 'fields', $default); | |||
} | |||
private function buildTransIdPanel($panelName, $entityClass, $default = false): string | |||
{ | |||
return $this->buildTransIdEntitySection($panelName, $entityClass, 'panels', $default); | |||
} | |||
private function buildTransIdEntitySection($name, $entityClass, $entitySection, $default): string | |||
{ | |||
if ($default) { | |||
$entityName = 'default'; | |||
@@ -105,26 +119,26 @@ class TranslatorAdmin | |||
$entityName = $this->getEntityName($entityClass); | |||
} | |||
return 'entity.' . $entityName . '.panels.' . $panelName; | |||
return 'entity.' . $entityName . '.' . $entitySection . '.' . $name; | |||
} | |||
private function trans($id, $params = [], $domain = self::DOMAIN): string | |||
public function trans($id, $params = [], $domain = self::DOMAIN): string | |||
{ | |||
return $this->translator->trans($id, $params, $domain); | |||
} | |||
private function getEntityName($entityClass): string | |||
{ | |||
if(is_object($entityClass)) { | |||
$entityClass = get_class($entityClass) ; | |||
if (is_object($entityClass)) { | |||
$entityClass = get_class($entityClass); | |||
} | |||
if(is_string($entityClass)) { | |||
if (is_string($entityClass)) { | |||
$entityNameExplode = explode('\\', $entityClass); | |||
return strtolower($entityNameExplode[count($entityNameExplode) - 1]); | |||
return $entityNameExplode[count($entityNameExplode) - 1]; | |||
} | |||
return 'default' ; | |||
return 'default'; | |||
} | |||
} | |||
@@ -66,6 +66,7 @@ class TwigExtension extends AbstractExtension | |||
new TwigFilter('lc_trans_admin_panel', [$this, 'lcTransAdminPanel']), | |||
new TwigFilter('lc_trans_admin_menu', [$this, 'lcTransAdminMenu']), | |||
new TwigFilter('lc_trans_admin_title', [$this, 'lcTransAdminTitle']), | |||
new TwigFilter('lc_trans_admin_action', [$this, 'lcTransAdminAction']), | |||
]; | |||
} | |||
@@ -96,7 +97,12 @@ class TwigExtension extends AbstractExtension | |||
public function lcTransAdminMenu($menuName) | |||
{ | |||
return $this->translator->trans('menu.' . $menuName, [], 'admin');; | |||
return $this->translatorAdmin->transMenu($menuName);; | |||
} | |||
public function lcTransAdminAction($actionName) | |||
{ | |||
return $this->translatorAdmin->transAction($actionName);; | |||
} | |||
public function lcTransAdminTitle($pageName, $entityClass = null, $params = []) |