Статус «Сохранено» должен объяснять, останется ли работа после закрытия страницы, принял ли её сервер и видят ли коллеги ту же версию. Это разные обещания. Редактору, в котором можно работать без подключения, нужно различать локальные изменения, данные, сохранённые на устройстве, ожидание синхронизации, подтверждённую синхронизацию и изменения, по которым требуется решение пользователя.
Представьте приложение для технического обслуживания, которым пользуются в здании с неустойчивой связью. Техник редактирует заметку об осмотре и повышает приоритет записи. В это же время координатор изменяет ту же запись из офиса. Задача дизайнера — не просто показать баннер об отсутствии сети, а защитить работу обоих людей и объяснить следующий шаг, когда у техника восстановится подключение.

Точно формулируйте, что означает каждый статус сохранения
Прежде чем писать тексты статусов, договоритесь с разработчиками, что именно приложение может подтвердить. Изменение в оперативной памяти ещё не означает, что оно надёжно сохранено на устройстве. Запрос в очереди — не успешная запись на сервере. А подтверждение записи на сервере не доказывает, что её уже получили все участники совместной работы.
| Состояние | Что известно | Подходящее сообщение и действие |
|---|---|---|
| Изменения в текущем представлении | Приложение держит изменение в памяти; сохранение ещё не подтверждено. | «Есть несохранённые изменения». Когда начнётся локальная запись, покажите «Сохраняем на этом устройстве…». Оставьте запись открытой до успешного сохранения или сообщите об ошибке и предложите способ восстановления. |
| Сохранено на этом устройстве | Приложение подтвердило выполнение предусмотренного в нём этапа локального сохранения. | «Сохранено на этом устройстве. Ещё не отправлено». Объясните, можно ли закрыть запись, а затем открыть её снова без потери изменений. |
| Ожидание синхронизации | Локальное изменение находится в очереди; подтверждения от сервера ещё нет. | «1 изменение ожидает синхронизации». Разрешайте продолжать редактирование только там, где реализация позволяет сохранить и последующие изменения. |
| Сохранение подтверждено сервером | Сервер подтвердил успешное сохранение нужной версии, а не просто получение запроса или его постановку в очередь на обработку. | «Синхронизировано в 09:42». Показывайте этот статус для текущего изменения, только если нет более новой локальной версии, которая ещё ожидает синхронизации. Подтверждение предыдущей версии не подтверждает сохранение последующей. |
| Конфликт версий | Запись на сервере изменилась. Чтобы применить изменение из очереди, нужно решить, какие значения сохранить в затронутых полях. | «Эта запись изменилась, пока вы были офлайн». Предложите сравнить версии, не теряя несинхронизированное изменение. |
Это определения состояний, а не требование одновременно показывать пять значков. Обычно достаточно одного ненавязчивого статуса рядом с названием записи. Сделайте его заметнее, когда человеку нужно что-то предпринять или возникает риск потери работы. Сообщение о нерешённой проблеме не должно исчезать вместе со всплывающим уведомлением.
Даже «Сохранено на этом устройстве» не обещает возможность восстановления в любой момент в будущем. Приватный режим браузера, правила хранения данных, смена аккаунта и сама реализация приложения могут ограничивать сохранность данных. Объясняйте конкретное ограничение тогда, когда оно влияет на следующий шаг пользователя; не скрывайте его за успокаивающей зелёной галочкой.
Считайте подключение подсказкой, а не доказательством сохранения
Индикатор сети не подтверждает, что ваш сервис принял запись. Устройство может быть подключено к сети, а сервис при этом недоступен. MDN также предупреждает: индикатор подключения браузера ненадёжен (документация на английском). Учитывайте этот сигнал в интерфейсе, но подтверждайте сохранение по результату самой операции.
Показывайте состояние сети отдельно от состояния записи. Сообщения «Подключение восстановлено» и «2 изменения ожидают синхронизации» могут быть верны одновременно. Если изменение приоритета, сделанное техником, всё ещё находится в очереди, общий статус «Всё сохранено» вместо этих двух сообщений скроет незавершённую работу.
При потере подключения оставьте на экране доступное для чтения содержимое и уже введённые данные. Отключайте только те действия, которые действительно нельзя выполнить безопасно. Если приложение поддерживает локальное редактирование заметки, оно может оставаться доступным, тогда как для отправки уведомления или назначения задания на обслуживание нужен сервер. Объясните это рядом с недоступным действием, не заменяя весь экран сообщением об ошибке.
Показывайте ожидающие изменения без лишних технических подробностей
Технику важно знать, какая запись ожидает синхронизации, а не сколько раз приложение повторило сетевой запрос. Разместите статус рядом с изменённой записью; компактный список очереди нужен, только если работа может затрагивать несколько записей. В счётчике называйте единицу подсчёта: «3 записи ожидают синхронизации» — не то же самое, что «3 изменения полей ожидают синхронизации».
Продумайте поведение очереди вместе с командой. Если человек дважды изменил одну заметку до восстановления связи, может ли приложение безопасно отправить только её последнее значение или нужно сохранить упорядоченную историю? Если второе действие возможно лишь после создания записи, не создавайте впечатление, что каждое из этих действий можно повторно выполнить независимо. Интерфейс должен отражать поддерживаемую модель, не заставляя пользователя разбираться в механизме передачи данных.
Показывайте понятную локальную отметку времени, если она помогает человеку узнать своё изменение. Но не считайте наиболее позднее из отображаемых значений времени универсальным основанием для выбора версии. Часы устройств, задержки запросов и порядок обработки на сервере могут сделать такой вывод неверным. Подписи «Ваше несинхронизированное изменение» и «Текущая версия на сервере» точнее объясняют нужное соотношение.
Покажите, что происходит после восстановления подключения
При восстановлении связи старое значение с сервера не должно даже ненадолго появляться вместо изменения, которое ещё ожидает отправки. Пока приложение проверяет и отправляет изменения, сохраняйте локальное рабочее представление. Если сервис успешно сохранит изменение, замените статус ожидания подтверждением именно для этой версии. Если во время запроса человек внесёт новое локальное изменение, оно по-прежнему должно отображаться как ожидающее синхронизации.
Полезный сценарий для проверки — два последовательных изменения заметки: приложение отправляет версию A, а до её подтверждения человек вводит версию B. Попросите разработчика показать, к какой версии относится подтверждение. Сообщение не должно объявлять B синхронизированной только потому, что A была успешно сохранена.
Если после отправки неясно, чем завершилась операция, не подталкивайте человека к действию, которое может создать дубликат. Команде нужен способ выяснить результат исходной операции. Спроектируйте видимое состояние ожидания или восстановления с учётом этого механизма. В примере с осмотром сообщение «Проверяем, получено ли это обновление» точнее, чем немедленное предложение отправить результаты осмотра ещё раз.
Сравнивайте спорные изменения, а не две записи без пояснений
Не каждое одновременное обновление требует модального окна. Если по правилам продукта изменения разных независимых полей можно безопасно объединить, приложение может сделать это и сообщить результат. Если оба человека изменили одно поле или одно изменение делает другое недопустимым, покажите затронутые поля и попросите принять решение, которое система не может безопасно принять сама.
В примере с осмотром у последней синхронизированной записи был приоритет «Низкий», а заметка была пустой. Техник установил приоритет «Срочный» и добавил заметку о протечке; координатор установил приоритет «Обычный», не меняя заметку. Приоритет изменили оба, но заметку — только техник. Покажите рядом локальные и текущие серверные значения, обозначьте запись и объясните последствия каждого выбора. Если сведения доступны и их разрешено показывать, добавьте автора или время соответствующего изменения. Никогда не раскрывайте информацию, к которой у человека больше нет доступа.
| Поле | Ваше несинхронизированное изменение | Текущая версия на сервере | Решение |
|---|---|---|---|
| Приоритет | Срочный | Обычный | Определите, какой приоритет следует применить; покажите выбранное значение перед подтверждением. |
| Заметка об осмотре | Под впускным клапаном видна протечка. | Пусто; без изменений относительно последней синхронизированной версии. | Сохраните заметку, если её можно добавить независимо. Не отбрасывайте её из-за того, что приоритет требует отдельного решения. |
Сравнение полезно, только если понятны последствия выбора. Кнопка «Оставить мою версию» слишком неоднозначна, если она заменяет сразу несколько полей. Лучше ограничить решение конкретным полем, например: «Установить срочный приоритет». Сохраняйте остальные локальные изменения. Если продукт позволяет объединить значения или отредактировать их вручную, явно предложите эту возможность, не вынуждая выбирать только одну из двух версий.
Пока открыто сравнение, запись может измениться снова. Разработчики должны предусмотреть это в согласованном поведении системы. При работе по HTTP условные запросы помогают предотвратить потерю обновлений (документация на английском). Для интерфейса из этого следует конкретное требование: если решение отклонено, потому что оно относится к уже устаревшей версии, нужно снова открыть сравнение с актуальными данными и сохранить предложенный пользователем вариант, а не молча перезаписывать более новую запись.
Отличайте конфликты от ошибок хранения, доступа и проверки данных
Не направляйте пользователя на один и тот же экран конфликта при любом сбое синхронизации. От причины зависит, что человек может сделать безопасно. Если локальное сохранение не удалось, после закрытия может не остаться черновика для восстановления. Если данные не прошли проверку, покажите поле, которое нужно исправить. Если изменились права доступа, повторная попытка не вернёт разрешение.
- Не удалось сохранить данные на устройстве: оставьте введённые данные видимыми, объясните, что не сохранено, и предложите разрешённый способ восстановления, если продукт его поддерживает.
- Срок действия сеанса истёк: объясните, что для продолжения нужно войти в аккаунт; сохраняйте изменение при переходе через повторный вход только там, где это допускают реализация и правила.
- Разрешение отозвано: остановите запись данных, на которую больше нет прав, и разрешайте восстановление или экспорт только в пределах действий, которые по-прежнему доступны этому человеку.
- Запись удалена: объясните, что запись, в которую предполагалось внести изменения, больше не существует. Её восстановление или создание новой — отдельное решение, зависящее от прав доступа, а не автоматическая повторная попытка.
- Правила проверки изменились: сохраните поля, которых это не касается, и покажите действующее правило рядом с полем, которое необходимо исправить.
Тексты и элементы управления должны учитывать эти различия. Предложение «Экспортировать черновик» может подходить владельцу записи в одном продукте, но быть небезопасным для участника, которому закрыли доступ, в другом. Прежде чем включать такой путь восстановления в дизайн, согласуйте допустимые действия с ответственными за безопасность и продукт.
Сделайте статусы понятными при работе с клавиатурой и скринридером
Размещайте текст статуса рядом с записью, к которой он относится, и дополняйте любой значок или цвет словами. Один вращающийся индикатор не объясняет, сохраняет ли приложение данные локально, обращается к серверу или ждёт ответа.
Обычные обновления статуса сохранения не должны уводить фокус из редактируемого поля. Сообщайте статус так, чтобы вспомогательные технологии могли определить его программно, и не озвучивайте каждое нажатие клавиши или повторную попытку. Рекомендации W3C по сообщениям о состоянии (на английском) различают обновления, которые можно сообщать без перемещения фокуса, и взаимодействия, меняющие контекст. Если диалог разрешения конфликта необходим, определите, как фокус попадает в него и куда возвращается после завершения или отмены.
Сохраняйте тот же путь восстановления и на узких экранах. Сравнение бок о бок можно преобразовать в два расположенных друг под другом блока с понятными подписями, повторив название поля перед каждым значением. Не различайте локальную и серверную версии только по горизонтальному расположению, красному и зелёному цвету или пояснению, доступному лишь при наведении.
Проверьте сценарий работы с записью об осмотре в Pixso
Создайте в файле Pixso три состояния одной записи об осмотре: локально сохранённую заметку, ожидающую синхронизации; сравнение конфликтующих значений приоритета; запись после принятия выбранного приоритета. Сохраняйте одинаковыми название записи, заметку и подписи полей. Между кадрами должны меняться состояние сохранения и решение, которое принимает человек.
Свяжите нужные экраны в прототипе и попросите коллегу продолжить осмотр после восстановления подключения. Может ли он понять, есть ли заметка на сервере, определить конфликтующие значения приоритета и разрешить конфликт этого поля, не потеряв заметку? Для передачи в разработку поясните в аннотациях разницу между подтверждением сервера и новым локальным изменением. В руководстве по передаче дизайна в разработку описан более общий подход к документированию таких технических решений.

Спроектируйте и проверьте сценарий разрешения конфликта синхронизации в Pixso →
Проверьте переходы, при которых изменения могут стать незаметными или потеряться
Проверяйте смену состояний, а не только отдельные экраны. Для записи об осмотре особенно показателен такой путь: редактирование офлайн, восстановление подключения, возникновение конфликта, а затем ещё одно изменение на сервере до его разрешения. Предложенный приоритет и исходная заметка должны оставаться понятными на всём протяжении сценария.
Также проверьте закрытие и повторное открытие после подтверждённого локального сохранения, сбой самого локального сохранения, редактирование поля во время выполнения запроса, истечение сеанса и отзыв доступа до восстановления подключения. Проверяйте только те гарантии повторного открытия, которые заявляет приложение. Зафиксируйте, сохраняются ли введённые данные, к какой версии относится каждое сообщение и остаётся ли каждое предлагаемое действие разрешённым.
Успешный результат — не просто пустая очередь. Техник должен понимать, какой приоритет принят, находить свою заметку об осмотре и знать, осталась ли работа, ожидающая синхронизации. Если интерфейс не отвечает на эти три вопроса, сначала доработайте статусы и восстановление и лишь затем полируйте анимацию.