diff --git a/assets/js/admin.js b/assets/js/admin.js index 1ae07eb..84a0624 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -3,7 +3,9 @@ import '../../vendor/murph/murph-core/src/core/Resources/assets/js/admin.js' const AddressAutocomplete = require('./modules/address.js') const FilesCollectionSorter = require('./modules/collection-sorter.js') const Calendar = require('./modules/calendar.js') +const Masks = require('./modules/masks.js') new AddressAutocomplete() new FilesCollectionSorter() new Calendar() +new Masks() diff --git a/assets/js/modules/masks.js b/assets/js/modules/masks.js new file mode 100644 index 0000000..574091e --- /dev/null +++ b/assets/js/modules/masks.js @@ -0,0 +1,21 @@ +const Inputmask = require('inputmask').default +const $ = require('jquery') + +class Masks { + constructor () { + this.applyMasks() + + $('*[data-collection]').on('collection.update', this.applyMasks) + } + + applyMasks () { + const elements = document.querySelectorAll('*[data-inputmask]') + + for (const element of elements) { + new Inputmask() + .mask(element) + } + } +} + +module.exports = Masks diff --git a/package.json b/package.json index 806bc53..883eb89 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "chunk": "^0.0.3", + "inputmask": "^5.0.8-beta.17", "murph-project": "^1", "vue-fragment": "^1.5.2" } diff --git a/src/Controller/TeamContactAdminController.php b/src/Controller/TeamContactAdminController.php new file mode 100644 index 0000000..61f0572 --- /dev/null +++ b/src/Controller/TeamContactAdminController.php @@ -0,0 +1,158 @@ +doIndex($page, $query, $request, $session); + } + + /** + * @Route("/admin/team_contact/new", name="admin_team_contact_new", methods={"GET", "POST"}) + */ + public function new(Factory $factory, EntityManager $entityManager, Request $request): Response + { + return $this->doNew($factory->create(), $entityManager, $request); + } + + /** + * @Route("/admin/team_contact/show/{entity}", name="admin_team_contact_show", methods={"GET"}) + */ + public function show(Entity $entity): Response + { + return $this->doShow($entity); + } + + /** + * @Route("/admin/team_contact/filter", name="admin_team_contact_filter", methods={"GET"}) + */ + public function filter(Session $session): Response + { + return $this->doFilter($session); + } + + /** + * @Route("/admin/team_contact/edit/{entity}", name="admin_team_contact_edit", methods={"GET", "POST"}) + */ + public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response + { + return $this->doEdit($entity, $entityManager, $request); + } + + /** + * @Route("/admin/team_contact/sort/{page}", name="admin_team_contact_sort", methods={"POST"}, requirements={"page":"\d+"}) + */ + public function sort(RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session, int $page = 1): Response + { + return $this->doSort($page, $query, $entityManager, $request, $session); + } + + /** + * @Route("/admin/team_contact/batch/{page}", name="admin_team_contact_batch", methods={"POST"}, requirements={"page":"\d+"}) + */ + public function batch(RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session, int $page = 1): Response + { + return $this->doBatch($page, $query, $entityManager, $request, $session); + } + + /** + * @Route("/admin/team_contact/delete/{entity}", name="admin_team_contact_delete", methods={"DELETE"}) + */ + public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response + { + return $this->doDelete($entity, $entityManager, $request); + } + + protected function getConfiguration(): CrudConfiguration + { + return CrudConfiguration::create() + ->setPageTitle('index', 'Contacts') + ->setPageTitle('edit', '{name}') + ->setPageTitle('new', 'Nouveau contact') + ->setPageTitle('show', '{name}') + + ->setPageRoute('index', 'admin_team_contact_index') + ->setPageRoute('new', 'admin_team_contact_new') + ->setPageRoute('edit', 'admin_team_contact_edit') + ->setPageRoute('show', 'admin_team_contact_show') + ->setPageRoute('sort', 'admin_team_contact_sort') + ->setPageRoute('batch', 'admin_team_contact_batch') + ->setPageRoute('delete', 'admin_team_contact_delete') + ->setPageRoute('filter', 'admin_team_contact_filter') + + ->setForm('edit', Type::class, []) + ->setForm('new', Type::class) + // ->setForm('filter', Type::class) + + // ->setMaxPerPage('index', 20) + + // ->setIsSortableCollection('index', false) + // ->setSortableCollectionProperty('sortOrder') + + ->setView('form', 'admin/team_contact/_form.html.twig') + + // ->setAction('index', 'new', true) + ->setAction('index', 'show', false) + // ->setAction('index', 'edit', true) + // ->setAction('index', 'delete', true) + + // ->setAction('edit', 'back', true) + ->setAction('edit', 'show', false) + // ->setAction('edit', 'delete', true) + + // ->setAction('show', 'back', true) + // ->setAction('show', 'edit', true) + + ->setField('index', 'Nom', Field\TextField::class, [ + 'property' => 'name', + 'attr' => ['class' => 'col-md-4'], + ]) + ->setField('index', 'Téléphones', Field\TextField::class, [ + 'property_builder' => function(EntityInterface $entity) { + return implode("
", array_map(fn($e) => $e['value'], $entity->getPhones())); + }, + 'raw' => true, + 'attr' => ['class' => 'col-md-4'], + ]) + ->setField('index', 'Emails', Field\TextField::class, [ + 'property_builder' => function(EntityInterface $entity) { + return implode("
", array_map(fn($e) => $e['value'], $entity->getEmails())); + }, + 'raw' => true, + 'attr' => ['class' => 'col-md-4'], + ]) + + // ->setField('index', 'Foo', Field\TextField::class, [ + // 'property' => 'foo', + // ]) + + // ->setBatchAction('index', 'delete', 'Delete', function(EntityInterface $entity, EntityManager $manager) { + // $manager->delete($entity); + // }) + ; + } + + protected function getSection(): string + { + return 'team_contact'; + } +} diff --git a/src/Entity/AddressTrait.php b/src/Entity/AddressTrait.php new file mode 100644 index 0000000..a58f9d3 --- /dev/null +++ b/src/Entity/AddressTrait.php @@ -0,0 +1,60 @@ +address; + } + + public function setAddress(string $address): self + { + $this->address = $address; + + return $this; + } + + public function getZipCode(): ?string + { + return $this->zipCode; + } + + public function setZipCode(string $zipCode): self + { + $this->zipCode = $zipCode; + + return $this; + } + + public function getCity(): ?string + { + return $this->city; + } + + public function setCity(string $city): self + { + $this->city = $city; + + return $this; + } +} diff --git a/src/Entity/Conference.php b/src/Entity/Conference.php index dff0440..5814813 100644 --- a/src/Entity/Conference.php +++ b/src/Entity/Conference.php @@ -59,12 +59,12 @@ class Conference implements EntityInterface /** * @ORM\Column(type="float", nullable=true) */ - private $price; + protected $price; /** * @ORM\ManyToMany(targetEntity=Speaker::class, inversedBy="conferences") */ - private $speakers; + protected $speakers; public function __construct() { diff --git a/src/Entity/Establishment.php b/src/Entity/Establishment.php index bbd7312..0e759f6 100644 --- a/src/Entity/Establishment.php +++ b/src/Entity/Establishment.php @@ -25,20 +25,7 @@ class Establishment implements EntityInterface */ protected $name; - /** - * @ORM\Column(type="string", length=255) - */ - protected $address; - - /** - * @ORM\Column(type="string", length=10) - */ - protected $zipCode; - - /** - * @ORM\Column(type="string", length=100) - */ - protected $city; + use AddressTrait; /** * @ORM\OneToMany(targetEntity=EstablishmentGroup::class, mappedBy="establishment", orphanRemoval=true, cascade={"persist", "remove"}) @@ -78,42 +65,6 @@ class Establishment implements EntityInterface return $this; } - public function getAddress(): ?string - { - return $this->address; - } - - public function setAddress(string $address): self - { - $this->address = $address; - - return $this; - } - - public function getZipCode(): ?string - { - return $this->zipCode; - } - - public function setZipCode(string $zipCode): self - { - $this->zipCode = $zipCode; - - return $this; - } - - public function getCity(): ?string - { - return $this->city; - } - - public function setCity(string $city): self - { - $this->city = $city; - - return $this; - } - /** * @return Collection */ diff --git a/src/Entity/Event.php b/src/Entity/Event.php index 6af172e..39dafa2 100644 --- a/src/Entity/Event.php +++ b/src/Entity/Event.php @@ -48,12 +48,12 @@ class Event implements EntityInterface /** * @ORM\ManyToMany(targetEntity=Speaker::class, inversedBy="events") */ - private $speakers; + protected $speakers; /** * @ORM\ManyToMany(targetEntity=Project::class, inversedBy="events") */ - private $projects; + protected $projects; public function __construct() { diff --git a/src/Entity/ExpenseReport.php b/src/Entity/ExpenseReport.php index fea36e7..171fc3f 100644 --- a/src/Entity/ExpenseReport.php +++ b/src/Entity/ExpenseReport.php @@ -16,58 +16,58 @@ class ExpenseReport implements EntityInterface * @ORM\GeneratedValue * @ORM\Column(type="integer") */ - private $id; + protected $id; /** * @ORM\ManyToOne(targetEntity=User::class, inversedBy="expenseReports") * @ORM\JoinColumn(nullable=false) */ - private $user; + protected $user; /** * @ORM\Column(type="array") */ - private $moves = []; + protected $moves = []; /** * @ORM\Column(type="array") */ - private $variousPayments = []; + protected $variousPayments = []; /** * @ORM\Column(type="datetime", nullable=true) */ - private $paidAt; + protected $paidAt; /** * @ORM\Column(type="array") */ - private $bills = []; + protected $bills = []; /** * @ORM\Column(type="date") */ - private $dateFrom; + protected $dateFrom; /** * @ORM\Column(type="date") */ - private $dateTo; + protected $dateTo; /** * @ORM\Column(type="float") */ - private $scalePerKilometer; + protected $scalePerKilometer; /** * @ORM\Column(type="boolean", options={"default"=0}) */ - private $isRequestedPayment = false; + protected $isRequestedPayment = false; /** * @ORM\Column(type="boolean", options={"default"=0}) */ - private $isPaid = false; + protected $isPaid = false; public function getId(): ?int { diff --git a/src/Entity/Intervention.php b/src/Entity/Intervention.php index 4a18dca..f03398e 100644 --- a/src/Entity/Intervention.php +++ b/src/Entity/Intervention.php @@ -94,7 +94,7 @@ class Intervention implements EntityInterface /** * @ORM\Column(type="float", nullable=true) */ - private $price; + protected $price; public function __construct() { diff --git a/src/Entity/Project.php b/src/Entity/Project.php index 8a9ffe6..deae1b9 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -53,12 +53,12 @@ class Project implements EntityInterface /** * @ORM\ManyToMany(targetEntity=Event::class, mappedBy="projects") */ - private $events; + protected $events; /** * @ORM\Column(type="float", nullable=true) */ - private $price; + protected $price; public function __construct() { diff --git a/src/Entity/Speaker.php b/src/Entity/Speaker.php index fa513b8..610b3bd 100644 --- a/src/Entity/Speaker.php +++ b/src/Entity/Speaker.php @@ -54,17 +54,17 @@ class Speaker implements EntityInterface, EncryptedEntityInterface /** * @ORM\ManyToMany(targetEntity=Event::class, mappedBy="speakers") */ - private $events; + protected $events; /** * @ORM\Column(type="string", length=30, nullable=true) */ - private $color; + protected $color; /** * @ORM\ManyToMany(targetEntity=Conference::class, mappedBy="speakers") */ - private $conferences; + protected $conferences; public function __construct() { diff --git a/src/Entity/TeamContact.php b/src/Entity/TeamContact.php new file mode 100644 index 0000000..211fd82 --- /dev/null +++ b/src/Entity/TeamContact.php @@ -0,0 +1,76 @@ +id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function getPhones(): ?array + { + return $this->phones; + } + + public function setPhones(array $phones): self + { + $this->phones = $phones; + + return $this; + } + + public function getEmails(): ?array + { + return $this->emails; + } + + public function setEmails(array $emails): self + { + $this->emails = $emails; + + return $this; + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 27c8860..a1a06bd 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -85,7 +85,7 @@ class User implements PasswordAuthenticatedUserInterface, UserInterface, TwoFact /** * @ORM\OneToMany(targetEntity=ExpenseReport::class, mappedBy="user", orphanRemoval=true) */ - private $expenseReports; + protected $expenseReports; public function __construct() { diff --git a/src/Factory/TeamContactFactory.php b/src/Factory/TeamContactFactory.php new file mode 100644 index 0000000..42591a6 --- /dev/null +++ b/src/Factory/TeamContactFactory.php @@ -0,0 +1,14 @@ +add( + 'value', + EmailType::class, + [ + 'label' => false, + 'required' => true, + 'constraints' => [ + new Email(), + new NotBlank(), + ], + ] + ); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + // Configure your form options here + ]); + } +} diff --git a/src/Form/ContactPhoneType.php b/src/Form/ContactPhoneType.php new file mode 100644 index 0000000..c58b8a1 --- /dev/null +++ b/src/Form/ContactPhoneType.php @@ -0,0 +1,38 @@ +add( + 'value', + TextType::class, + [ + 'label' => false, + 'required' => true, + 'help' => 'Format international, exemple : +33 (0)6 11 22 33 44', + 'attr' => [ + 'data-inputmask' => "'mask': '+99 (9)9 99 99 99 99'", + ], + 'constraints' => [ + new NotBlank(), + ], + ] + ); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + // Configure your form options here + ]); + } +} diff --git a/src/Form/TeamContactType.php b/src/Form/TeamContactType.php new file mode 100644 index 0000000..cbe56fa --- /dev/null +++ b/src/Form/TeamContactType.php @@ -0,0 +1,50 @@ +add('name') + ->add('phones', CollectionType::class, [ + 'collection_name' => 'phones_collection', + 'entry_type' => ContactPhoneType::class, + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => false, + 'prototype' => true, + 'label' => 'Téléphone(s)', + 'row_attr' => [ + 'class' => 'col-md-12', + ], + ]) + ->add('emails', CollectionType::class, [ + 'collection_name' => 'emails_collection', + 'entry_type' => ContactEmailType::class, + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => false, + 'prototype' => true, + 'row_attr' => [ + 'class' => 'col-md-12', + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => TeamContact::class, + ]); + } +} diff --git a/src/Repository/TeamContactRepository.php b/src/Repository/TeamContactRepository.php new file mode 100644 index 0000000..1c4bc7c --- /dev/null +++ b/src/Repository/TeamContactRepository.php @@ -0,0 +1,66 @@ + + * + * @method TeamContact|null find($id, $lockMode = null, $lockVersion = null) + * @method TeamContact|null findOneBy(array $criteria, array $orderBy = null) + * @method TeamContact[] findAll() + * @method TeamContact[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class TeamContactRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, TeamContact::class); + } + + public function add(TeamContact $entity, bool $flush = false): void + { + $this->getEntityManager()->persist($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + public function remove(TeamContact $entity, bool $flush = false): void + { + $this->getEntityManager()->remove($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + +// /** +// * @return TeamContact[] Returns an array of TeamContact objects +// */ +// public function findByExampleField($value): array +// { +// return $this->createQueryBuilder('t') +// ->andWhere('t.exampleField = :val') +// ->setParameter('val', $value) +// ->orderBy('t.id', 'ASC') +// ->setMaxResults(10) +// ->getQuery() +// ->getResult() +// ; +// } + +// public function findOneBySomeField($value): ?TeamContact +// { +// return $this->createQueryBuilder('t') +// ->andWhere('t.exampleField = :val') +// ->setParameter('val', $value) +// ->getQuery() +// ->getOneOrNullResult() +// ; +// } +} diff --git a/src/Repository/TeamContactRepositoryQuery.php b/src/Repository/TeamContactRepositoryQuery.php new file mode 100644 index 0000000..f00faa0 --- /dev/null +++ b/src/Repository/TeamContactRepositoryQuery.php @@ -0,0 +1,15 @@ + - {{ include('@Core/admin/module/_menu_section.html.twig', {label: 'Divers'}) }} + {{ include('@Core/admin/module/_menu_section.html.twig', {label: 'Comptabilité'}) }} + + {{ include('@Core/admin/module/_menu_section.html.twig', {label: 'Annuaire'}) }} + + {% endif %} diff --git a/templates/admin/team_contact/_form.html.twig b/templates/admin/team_contact/_form.html.twig new file mode 100644 index 0000000..8306275 --- /dev/null +++ b/templates/admin/team_contact/_form.html.twig @@ -0,0 +1,13 @@ +
+
+ {% for item in ['name'] %} + {% include(configuration.view('form_widget', '@Core/admin/crud/_form_widget.html.twig')) with {form: form[item]} %} + {% endfor %} +
+ {% for item in ['phones', 'emails'] %} +
+ {% include(configuration.view('form_widget', '@Core/admin/crud/_form_widget.html.twig')) with {form: form[item]} %} +
+ {% endfor %} +
+ diff --git a/yarn.lock b/yarn.lock index 0c6c4f8..1973263 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2874,7 +2874,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -4523,7 +4523,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -4570,6 +4570,11 @@ init-package-json@^1.10.3: validate-npm-package-license "^3.0.1" validate-npm-package-name "^3.0.0" +inputmask@^5.0.8-beta.17: + version "5.0.8-beta.17" + resolved "https://registry.yarnpkg.com/inputmask/-/inputmask-5.0.8-beta.17.tgz#549ab1157046e3b516ad2d0047c7c72b11e77e1e" + integrity sha512-7WnTpc63xjTnbGEy62IBnTy532L2jWb4obtxJW/lPJPJAupuvgPvGIiHi5Asu9d6IB+crs94POr+lD3DVBm/2Q== + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -5269,11 +5274,6 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -5282,33 +5282,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - lodash._root@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" @@ -5389,11 +5367,6 @@ lodash.reject@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.some@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"