fix from field

This commit is contained in:
Paul Lützner committed 2026-07-07 18:14:42 +02:00
1 parent 3a383f50ff
commit 100c2ae6e7
7 files changed
+87 -73

No files matched your search

+2 -1
View File
@@ -18,7 +18,6 @@ export default class extends Controller {
this._boundAutosave = this._scheduleAutosave.bind(this)
const form = this.element.querySelector('form');
console.log(this.element);
const formAction = this.element.dataset.composeSendUrlValue;
form?.addEventListener('input', this._boundAutosave);
form.action = formAction;
@@ -36,6 +35,7 @@ export default class extends Controller {
if (window.innerWidth < 768) {
this.expandedValue = true
}
console.log(this.accountSelectTarget.value);
}
disconnect() {
@@ -141,6 +141,7 @@ export default class extends Controller {
}
selectAccount(event) {
console.log(this.accountSelectTarget.value);
const btn = event.currentTarget
const value = btn.dataset.value
const label = btn.dataset.label
+19 -25
View File
@@ -25,16 +25,20 @@ class ComposeController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly MailboxRepository $mailboxRepository,
private readonly MessageBusInterface $bus,
) {}
private readonly MailboxRepository $mailboxRepository,
private readonly MessageBusInterface $bus,
)
{
}
#[Route('/new', name: 'new', methods: ['GET'])]
#[Route('/edit/{id}', name: 'edit', methods: ['GET'])]
public function compose(?Message $message = null): Response
{
if(null === $message) {
$message = new Message();
if (null === $message) {
$message = new Message()
->setMailbox($this->mailboxRepository->findPrimaryDraftMailboxForUser($this->getUser()))
->setCreatedAt(new DateTimeImmutable());
}
$form = $this->createForm(ComposeType::class, $message, [
@@ -52,8 +56,10 @@ class ComposeController extends AbstractController
#[Route('/draft/{id}', name: 'form_edit', methods: ['POST'])]
public function draft(Request $request, ?Message $message = null): Response
{
if(null === $message) {
$message = new Message();
if (null === $message) {
$message = new Message()
->setMailbox($this->mailboxRepository->findPrimaryDraftMailboxForUser($this->getUser()))
->setCreatedAt(new DateTimeImmutable());
}
$form = $this->createForm(ComposeType::class, $message, [
@@ -64,7 +70,7 @@ class ComposeController extends AbstractController
$form->handleRequest($request);
if (true === $form->isSubmitted() && true === $form->isValid()) {
$this->persistDraft($form, $message);
$this->persistDraft($message);
return $this->render('compose/_window.html.twig', [
'form' => $form,
@@ -84,7 +90,7 @@ class ComposeController extends AbstractController
#[Route('/send/{id}', name: 'mail_send_draft', methods: ['POST'])]
public function send(Request $request, ?Message $message): Response
{
if(null === $message) {
if (null === $message) {
$message = new Message();
}
@@ -137,28 +143,16 @@ class ComposeController extends AbstractController
]);
}
private function persistDraft(FormInterface $form, Message $message): void
private function persistDraft(Message $message): void
{
/** @var Account $account */
$account = $form->get('account')->getData();
$draftsMailbox = $this->mailboxRepository->findDraftMailboxForAccount($account);
if (!$draftsMailbox instanceof Mailbox) {
throw new RuntimeException('No Drafts mailbox found for the selected account.');
}
$now = new DateTimeImmutable();
$message
->setMailbox($draftsMailbox)
->setFromAddress($account->getEmail())
->setFromName($account->getName())
->setFromAddress($message->getMailbox()->getAccount()->getEmail())
->setFromName($message->getMailbox()->getAccount()->getName())
->addFlag(MessageFlag::DRAFT)
->setHasAttachments(false)
->setCreatedAt($now)
->setUpdatedAt($now)
;
->setUpdatedAt($now);
$this->em->persist($message);
$this->em->flush();
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace App\Domain\Enum;
enum MailboxSpecialUse: string
{
case INBOX = '\\Inbox';
case SENT = '\\Sent';
case TRASH = '\\Trash';
case DRAFTS = '\\Drafts';
case JUNK = '\\Junk';
}
+12 -12
View File
@@ -3,8 +3,11 @@
namespace App\Form;
use App\Entity\Account;
use App\Entity\Mailbox;
use App\Entity\Message;
use App\Repository\MailboxRepository;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
@@ -32,21 +35,17 @@ class ComposeType extends AbstractType
$builder
// From — EntityType scoped to the current user's accounts
->add('account', EntityType::class, [
->add('mailbox', EntityType::class, [
'label' => false,
'class' => Account::class,
'choice_label' => fn(Account $a) => $a->getFromHeader(),
'query_builder' => fn(EntityRepository $er) => $er
->createQueryBuilder('a')
->where('a.usr = :user')
->andWhere('a.isActive = true')
->orderBy('a.isPrimary', 'DESC')
->addOrderBy('a.email', 'ASC')
->setParameter('user', $user),
'class' => Mailbox::class,
'choice_label' => fn(Mailbox $mailbox) => sprintf('%s <%s>',$mailbox->getAccount()->getName(),$mailbox->getAccount()->getEmail()),
'query_builder' => function (MailboxRepository $repo) use ($user): QueryBuilder {
return $repo->getActiveSentMailboxesForUser($user);
},
// Pre-select the primary account
'preferred_choices' => fn(Account $a) => $a->isPrimary(),
'mapped' => false, // Controller resolves mailbox from this and sets it on Message
// 'preferred_choices' => fn(Account $a) => $a->isPrimary(),
'attr' => ['class' => 'compose-from-select'],
// 'data' => $options['selected_account'],
])
// To — always visible, at least one entry required
@@ -119,6 +118,7 @@ class ComposeType extends AbstractType
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Message::class,
'action' => $this->router->generate('app_compose_mail_send'),
-24
View File
@@ -16,28 +16,4 @@ class AccountRepository extends ServiceEntityRepository
parent::__construct($registry, Account::class);
}
// /**
// * @return Account[] Returns an array of Account objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Account
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}
+34 -3
View File
@@ -2,10 +2,13 @@
namespace App\Repository;
use App\Domain\Enum\MailboxSpecialUse;
use App\Domain\Enum\MessageFlag;
use App\Entity\Account;
use App\Entity\Mailbox;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\User\UserInterface;
@@ -33,11 +36,11 @@ class MailboxRepository extends ServiceEntityRepository
public function findSentMailboxForAccount(Account $account): ?Mailbox
{
return $this->findOneBy(['account' => $account, 'specialUse' => '\\Sent']);
return $this->findOneBy(['account' => $account, 'specialUse' => MailboxSpecialUse::SENT]);
}
public function findDraftMailboxForAccount(Account $account): ?Mailbox
{
return $this->findOneBy(['account' => $account, 'specialUse' => '\\Drafts']);
return $this->findOneBy(['account' => $account, 'specialUse' => MailboxSpecialUse::DRAFTS]);
}
public function findIdleEnabledAndSyncEnabled(): array
@@ -67,8 +70,36 @@ class MailboxRepository extends ServiceEntityRepository
->andWhere('mailbox.specialUse = :inbox')
->setParameter('isActive', true)
->setParameter('usr', $user)
->setParameter('inbox', '\\Inbox')
->setParameter('inbox', MailboxSpecialUse::INBOX)
->getQuery()
->getSingleColumnResult();
}
public function getActiveSentMailboxesForUser(UserInterface $user): QueryBuilder
{
return $this->createQueryBuilder('mailbox')
->leftJoin('mailbox.account', 'account')
->where('account.isActive = :isActive')
->andWhere('account.usr = :usr')
->andWhere('mailbox.specialUse = :sent')
->setParameter('isActive', true)
->setParameter('usr', $user)
->setParameter('sent', MailboxSpecialUse::DRAFTS)
->orderBy('account.isPrimary', 'DESC');
}
public function findPrimaryDraftMailboxForUser(UserInterface $user){
return $this->createQueryBuilder('mailbox')
->leftJoin('mailbox.account', 'account')
->where('account.isActive = :isActive')
->andWhere('account.usr = :usr')
->andWhere('mailbox.specialUse = :drafts')
->andWhere('account.isPrimary = :isPrimary')
->setParameter('isActive', true)
->setParameter('usr', $user)
->setParameter('drafts', MailboxSpecialUse::DRAFTS)
->setParameter('isPrimary', true)
->getQuery()
->getSingleResult();
}
}
+8 -8
View File
@@ -60,13 +60,13 @@
class="flex flex-col flex-1 min-h-0">
{# ── Hidden account select (submitted with form) ───────── #}
<select id="{{ form.account.vars.id }}"
name="{{ form.account.vars.full_name }}"
<select id="{{ form.mailbox.vars.id }}"
name="{{ form.mailbox.vars.full_name }}"
data-compose-target="accountSelect"
class="sr-only">
{% for choice in form.account.vars.choices %}
{% for choice in form.mailbox.vars.choices %}
<option value="{{ choice.value }}"
{% if form.account.vars.value == choice.value %}selected{% endif %}>
{% if form.mailbox.vars.value == choice.value %}selected{% endif %}>
{{ choice.label }}
</option>
{% endfor %}
@@ -83,8 +83,8 @@
class="flex-1 flex items-center justify-between gap-2 text-sm
text-gray-700 dark:text-gray-300 text-left">
<span data-compose-target="fromLabel" class="truncate">
{% for choice in form.account.vars.choices %}
{% if form.account.vars.value == choice.value %}{{ choice.label }}{% endif %}
{% for choice in form.mailbox.vars.choices %}
{% if form.mailbox.vars.value == choice.value %}{{ choice.label }}{% endif %}
{% endfor %}
</span>
<i class="fa-solid fa-chevron-down text-[10px] text-gray-400 dark:text-gray-500 shrink-0 transition-transform duration-150"
@@ -98,7 +98,7 @@
backdrop-blur-sm
border border-gray-200/60 dark:border-white/10
shadow-xl shadow-black/15 dark:shadow-black/50">
{% for choice in form.account.vars.choices %}
{% for choice in form.mailbox.vars.choices %}
<button type="button"
data-action="click->compose#selectAccount"
data-value="{{ choice.value }}"
@@ -108,7 +108,7 @@
hover:bg-blue-50 dark:hover:bg-blue-500/20
hover:text-blue-600 dark:hover:text-blue-300
transition-colors
{% if form.account.vars.value == choice.value %}
{% if form.mailbox.vars.value == choice.value %}
bg-blue-50 dark:bg-blue-500/10 text-blue-600 dark:text-blue-300
{% endif %}">
{{ choice.label }}