f7cloud_client/apps/mail/CHANGELOG-F7CLOUD.md
root 8b6a0139db f7cloud_client
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 22:59:26 +00:00

10 KiB
Raw Permalink Blame History

Changelog — доработки F7cloud

Журнал кастомных изменений, внесённых в приложения и ядро F7cloud (на базе F7cloud).


Приложение Mail

Поиск на русском языке и регистронезависимость

  • lib/Service/Search/FilterStringParser.php

    • Для поисковых терминов (в т.ч. с префиксами from:, to:, subject:, body:) добавлена передача в запрос варианта с первой заглавной буквой (title-case), чтобы поиск по кириллице работал с LIKE в PostgreSQL при локали C.
    • Добавлены проверки is_string и на непустоту для результатов mb_convert_case для устойчивости.
  • lib/Db/MessageMapper.php

    • Для полей label, email и m.subject заменён iLike на LIKE с COALESCE, чтобы поиск корректно работал при разных локалях БД.
  • lib/private/DB/SQLiteSessionInit.php (ядро)

    • Зарегистрирована пользовательская функция LOWER для SQLite на базе mb_strtolower для корректной работы поиска в SQLite.

Расширенный поиск — автозаполнение и очистка

  • src/components/SearchMessages.vue
    • Удалена логика, которая подставляла значение обычного поиска (query) в поля расширенного поиска (Тема, От, Кому, Тело письма).
    • Добавлена watch на открытие модального окна расширенного поиска: при активном только простом запросе поля расширенного поиска сбрасываются.
    • Изменено вычисляемое свойство searchQuery: при пустом query и отсутствии расширенных фильтров возвращается пустая строка вместо "match:anyof", чтобы избежать ошибки 500 при очистке фильтра.

Ошибка 500 и «не удалось открыть папку» при поиске

  • lib/Service/Search/MailSearch.php
    • Вызов IMAP-поиска (imapSearchProvider->findMatches) обёрнут в try-catch; при ошибке (в т.ч. из‑за кириллицы на стороне IMAP) используется только поиск по БД (fallback).

Отображение групп при выборе получателей

  • lib/Service/GroupsIntegration.php
    • Для групп из сервиса с namespace F7cloud подпись больше не дополняется суффиксом в скобках: показывается только имя группы (например, «all» вместо «all (F7cloud)»).
    • Для остальных источников групп (например, контакты) по‑прежнему выводится имя и в скобках источник.

Ядро (lib)

Отображаемые имена групп

  • lib/private/Group/Database.php
    • Добавлен метод stripInstanceSuffixFromDisplayName(): убирает суффикс (F7cloud) в конце отображаемого имени группы.
    • В getDisplayName() и при формировании результата в getGroupsDetails() возвращаемое имя группы очищается от этого суффикса (для единообразия в шаринге и других местах).

Приложение Contacts

Локализация (брендинг F7cloud)

  • l10n/ru.json, l10n/ru.js
    • В русских переводах заменено «F7cloud» на «F7cloud» (название приложения, описания, пункт «Выбрать в F7cloud» и т.п.).

Прочее

Владелец изменённых файлов

  • .cursor/rules/file-ownership.mdc (в проекте)
    • Правило Cursor: для изменённых файлов в /var/www/f7cloud/ выполнять chown www-data:www-data.


Шаринг папок почты (завершено)

Реализация по плану docs/PLAN-FOLDER-SHARING.md доведена до рабочего состояния; этап 7 (тесты и доработки) считается завершённым — функционал работает и отображается как задумано.

Этап 1 — модель данных и подпапки с первого дня

  • План: docs/PLAN-FOLDER-SHARING.md — шаринг папок с пользователями/группами, два уровня прав (только просмотр / полный доступ), блок «Папки других пользователей»; подпапки отображаются и доступны с самого начала.
  • Миграция lib/Migration/Version5007Date20260204120000.php: создаётся таблица mail_mailbox_shares (owner_user_id, account_id, mailbox_id, share_type, share_with, permission, created_at).
  • Сущность lib/Db/MailboxShare.php: константы TYPE_USER, TYPE_GROUP, PERMISSION_READ, PERMISSION_READ_WRITE.
  • Маппер lib/Db/MailboxShareMapper.php: find, findByMailbox, findSharedWith(userOrGroupIds), shareExists, deleteById, deleteByMailbox, findByOwner.

Этап 2 — сервис и API

  • Сервис lib/Service/MailboxShareService.php: createShare, deleteShare, getSharesForMailbox, getSharedWithMe (владелец, папка, подпапки по префиксу имени), getShareForUser, getShareForMailboxAccess (доступ по шару для текущего пользователя). Используется MailboxMapper для проверки доступа к папке/подпапке.
  • Контроллер lib/Controller/MailboxShareController.php: POST /api/mailboxes/{id}/share (shareWith, shareType, permission), DELETE /api/mailbox-shares/{shareId}, GET /api/mailboxes/{id}/shares, GET /api/mailbox-shares (shared with me). Проверка владельца папки/шара, JsonResponse + TrapError.
  • Маршруты в appinfo/routes.php: добавлены четыре маршрута для mailboxShare#create, destroy, index, sharedWithMe.

Этап 3 — доступ к папкам и письмам по шару

  • Сервис lib/Service/MailboxShareService.php: добавлены resolveMailboxForAccess(currentUserId, mailboxId, ?shareId) и resolveMessageAccess(currentUserId, messageId, ?shareId) — возвращают mailbox/account (и при shared — share) или null при отсутствии доступа.
  • MessagesController: во все методы, работающие с папкой или сообщением, добавлен опциональный параметр ?int $shareId = null. При переданном shareId доступ разрешается через резолвер (от имени владельца шаринга). Затронуты: index, show, getFilterHeaders, getBody, getItineraries, getDkim, getThread, move, snooze, unSnooze, mdn, getSource, export, getHtmlBody, downloadAttachment, downloadAttachments, saveAttachment, setFlags, setTag, removeTag, destroy, smartReply, needsTranslation.
  • MailboxesController: для sync, clearCache, markAllAsRead, stats добавлен ?int $shareId = null и использование resolveMailboxForAccess.
  • ThreadController: для move, snooze, unSnooze, summarize, generateEventData, delete добавлен ?int $shareId = null и использование resolveMessageAccess / resolveMailboxForAccess.

Этапы 67 учтены в текущей реализации; при необходимости доработки по праву «только просмотр» или граничным случаям — отдельные записи.

Этап 45 — навигация: группировка по владельцу и локализация

  • src/components/Navigation.vue

    • Блок расшаренных папок переименован по смыслу: заголовок использует ключ «Network mail folders» (см. локализацию ниже), отображается как группа, а не плоский список.
    • Группировка по владельцу: расшаренные папки сведены в группы по ownerUserId. Каждый владелец — одна раскрывающаяся строка (имя + шеврон ▼/▶), внутри — его расшаренные папки (основная + подпапки). Состояние раскрытия хранится в sharedGroupOpen (по умолчанию группы открыты).
    • Добавлены computed sharedWithMeGrouped, методы toggleSharedGroup и isSharedGroupOpen, импорты иконок ChevronDown/ChevronRight.
    • Заголовок секции уменьшен: класс mail-navigation__shared-heading--small (шрифт 0.85rem, font-weight 500). Стили для кнопки-заголовка группы (.mail-navigation__shared-caption, .mail-navigation__shared-chevron, .mail-navigation__shared-caption-text).
  • Локализация

    • l10n/ru.json: добавлена строка "Network mail folders" : "Сетевые почтовые папки".
    • l10n/ru.js: добавлена строка "Network mail folders": "Сетевые почтовые папки" (для корректного отображения перевода на фронтенде).

Документ составлен по результатам доработок под F7cloud. При обновлении приложений или ядра из upstream эти правки могут потребовать переноса или проверки совместимости.