Сотрудник открывает карточку из отфильтрованного списка, возвращается назад и видит весь список заново. Ниже — как разложить состояние фильтра по слоям и не терять контекст при возврате, перезагрузке и переходе по чужой ссылке.
Применённый фильтр храните в адресе страницы как единственный источник правды, а локальное хранилище используйте только как значение по умолчанию. При смене фильтра заменяйте запись истории, новую добавляйте лишь при входе в карточку. Неприменённый ввод держите отдельно от фильтра. При восстановлении сверяйте условия с текущими правами и не помещайте в ссылку секреты и персональные данные.
Сотрудник открывает из отфильтрованного списка заявку, правит статус, возвращается назад — и видит весь список заново, без города, без периода, без менеджера. Условная сцена: двадцать минут работы по отбору исчезли, потому что приложение не помнит, зачем его открыли.
Механизм тут не в «умном кэше», а в разделении четырёх разных вещей, которые обычно сваливают в одну переменную: что записано в адресе страницы, что лежит в истории браузера, что хранится локально на устройстве и что сотрудник набрал, но ещё не применил. Пока эти слои смешаны, любой возврат ломает то один, то другой. Ниже — рабочая методика, как разложить их по местам и не потерять контекст списка.

Адрес страницы как переносчик условий отбора
Первое решение, которое определяет всё остальное: условие отбора живёт в адресе или в памяти приложения. Если в адресе — ссылку можно переслать, закладку сохранить, а обновление страницы ничего не разрушит. Если в памяти — после перезагрузки остаётся пустота.
Практическая рекомендация: считать адрес единственным источником правды для применённого фильтра. Всё, что сотрудник реально применил, попадает в параметры строки запроса; всё, что он только набирает в поле поиска, там не появляется до нажатия «применить». Это различие снимает половину будущих споров.
Есть цена. Адрес с десятком параметров выглядит неопрятно, а длинные значения упираются в ограничения длины URL. Поэтому в ссылку кладут идентификаторы и короткие значения, а не целые объекты. И никогда — персональные данные, токены доступа или что-то, что нельзя показывать в чужой истории браузера и логах прокси. Про то, что попадает в адрес, а что нет, стоит договориться до первой строки кода, а не после инцидента.
Если ваша задача — сохранить контекст рабочего списка, на странице соответствующего направления 404ai можно посмотреть опубликованные возможности и оставить описание текущего процесса. Конкретные подключения, исходные данные и критерии приёмки согласуем отдельно.
Что история браузера делает с вашим фильтром
Кнопка «назад» — не то же самое, что повторный переход по ссылке. Браузер хранит последовательность состояний, и при возврате восстанавливает запись из истории, а не заново запрашивает страницу с текущими параметрами. Это поведение описано в документации по History API: каждая запись несёт своё состояние, и приложение может его прочитать при возврате. (MDN: History API)
Отсюда типичная ошибка: приложение при каждом изменении фильтра дописывает новую запись в историю. Сотрудник меняет город, период, статус — и чтобы вернуться к списку заявок, ему нужно нажать «назад» четыре раза. История превращается в свалку промежуточных состояний.
Разумнее заменять текущую запись при изменении фильтра и добавлять новую только при переходе в карточку. Тогда «назад» из карточки ведёт ровно к тому списку, из которого сотрудник ушёл, с теми же условиями. А если он поменял фильтр и остался на списке — «назад» уводит его туда, откуда он пришёл в приложение, а не прокручивает его же шаги.
Локальное хранилище: что помнить между сеансами
Адрес решает задачу возврата внутри одной сессии. Но сотрудник закрывает вкладку и открывает приложение утром — и хочет видеть тот же рабочий срез, а не чистый список. Здесь вступает локальное хранилище браузера: оно переживает перезагрузку и закрытие вкладки, но привязано к конкретному устройству и браузеру. (MDN: Web Storage API)
Правило, которое стоит закрепить: локально хранится последний применённый фильтр как значение по умолчанию, а адрес имеет приоритет над ним. Открыли ссылку с параметрами — показываем то, что в ссылке. Открыли приложение без параметров — подставляем сохранённый срез. Это предсказуемо и объяснимо сотруднику одной фразой.
Второй слой — несохранённый ввод. Сотрудник набрал в поле поиска «Иванов», не нажал «применить», ушёл в карточку и вернулся. Показывать ли набранное? Скорее да, но отдельно от применённого фильтра: поле с текстом, рядом явная пометка, что фильтр не применён. Иначе человек уверен, что список отфильтрован, а на деле видит всё.
| Слой | Что хранит | Живёт | Приоритет |
|---|---|---|---|
| Адрес страницы | Применённый фильтр, короткие значения | Пока открыта ссылка | Высший |
| История браузера | Состояние на момент перехода | В рамках сеанса | Средний |
| Локальное хранилище | Последний применённый срез | Между сеансами | Низший |
| Память приложения | Неприменённый ввод | До перезагрузки | Отдельно от фильтра |
Сохранённый выбор фильтров: что именно мы сохраняем
Прежде чем писать код, стоит описать сам объект фильтра — иначе каждый разработчик придумает свою структуру. Условная форма может выглядеть так: набор полей отбора (город, период, статус, ответственный), способ сортировки, номер страницы и версия схемы. Версия нужна, потому что через полгода вы добавите новое поле, а у сотрудника в хранилище лежит старый объект без него.
Отдельно фиксируется, какие поля обязательны, какие имеют значение по умолчанию и что считается «пустым» фильтром. Пустой фильтр — это не отсутствие объекта, а явное состояние «показать всё». Разница принципиальна: если пустоту трактовать как «нет данных», приложение начнёт подставлять сохранённый срез там, где сотрудник осознанно сбросил отбор.
Хорошая привычка — сериализовать объект в одну короткую строку и держать её в одном месте: и для адреса, и для хранилища. Тогда не возникнет ситуации, когда в ссылке период записан одним способом, а в локальном кэше — другим, и при переключении между ними фильтр «съезжает».
Возврат назад: где ломается контекст
Разберём условный эпизод. Менеджер отбирает заявки по городу и статусу «в работе», открывает первую, меняет ответственного, жмёт «назад». Если приложение заменяло запись истории при смене фильтра и добавило запись при входе в карточку — возврат приводит к тому же отфильтрованному списку, прокрутка на прежнем месте, ничего не мигает.
А теперь тот же эпизод, но фильтр хранился только в памяти компонента. Возврат перерисовывает список с нуля, условия теряются, сотрудник заново выставляет город и статус. На десяти карточках за смену это уже не мелочь, а реальные минуты, которые никто не считает.
Третий вариант — фильтр в адресе, но при возврате приложение заново запрашивает данные и на время загрузки показывает пустую таблицу. Формально условия сохранены, фактически сотрудник видит «ничего не найдено» на секунду и нервничает. Решение — сохранять последний отрисованный результат и показывать его до прихода свежего, а не стирать экран.
Перезагрузка и открытие по ссылке
Перезагрузка страницы — самый честный тест. Если после F5 список возвращается к тем же условиям, значит адрес действительно работает как источник правды. Если нет — где-то фильтр живёт в памяти, и вы это просто ещё не заметили.
Ссылка коллеге — второй тест, и он коварнее. Сотрудник копирует адрес с фильтром и отправляет в чат. Коллега открывает — и видит либо пустоту, либо чужие данные, либо ошибку доступа. Причина в том, что фильтр в ссылке описывает условия отбора, но не права. Если в адресе оказался недоступный идентификатор ответственного, сервер заново проверяет права, а интерфейс сообщает, что заданный отбор неприменим. Нельзя молча удалить ограничение и показать более широкий список. Пользователь выбирает разрешённые условия явно.
Отсюда рекомендация: в ссылку кладут только то, что имеет смысл для другого человека с теми же правами. Идентификаторы сущностей — да. Токены, персональные данные, внутренние флаги — нет. А при открытии ссылки приложение сверяет условия с текущими полномочиями и мягко корректирует, а не молча подменяет.
Пустая страница после удаления и устаревший фильтр
Условный эпизод второй. Сотрудник отфильтровал заявки по конкретному клиенту, открыл одну, удалил её — и вернулся к списку, где больше нет ни одной записи по этому клиенту. Экран пуст, и непонятно: то ли фильтр слишком узкий, то ли данные пропали, то ли что-то сломалось.
Пустое состояние — это отдельный экран, а не пустая таблица. В нём должно быть видно, какие условия применены, и одна понятная кнопка «сбросить фильтр». Сотрудник должен за секунду понять, что список пуст из-за его же отбора, а не из-за сбоя.
Похожая история — устаревший фильтр. Человек сохранил срез полгода назад, за это время статусы переименовали, а одно поле убрали. Приложение открывает старый объект и молча игнорирует незнакомые поля. Пользователь видит не тот список, который ожидал. Поэтому в объекте фильтра есть версия схемы, и при несовпадении приложение либо мигрирует условия, либо честно сбрасывает их с пояснением.
| Ситуация | Что видит сотрудник | Правильное поведение |
|---|---|---|
| Удалил последнюю запись в срезе | Пустая таблица | Экран «нет данных по условиям» + сброс |
| Открыл старый сохранённый фильтр | Странный набор записей | Миграция или явный сброс с пояснением |
| Перешёл по ссылке без прав на часть условий | Ошибка или чужие данные | Показать доступное, отметить недоступное |
| Нажал «назад» после смены фильтра | Промежуточные состояния | Одна запись на список, не на каждое изменение |
Изменённые права и чужая ссылка
Права меняются не только у коллеги, но и у самого сотрудника. Условно: вчера он видел заявки всех менеджеров, сегодня ему оставили только свои. Сохранённый фильтр «ответственный = все» при открытии даёт пустой или урезанный список, и человек думает, что данные пропали.
Приложение при восстановлении фильтра сверяет каждое условие с текущими полномочиями. Недоступное условие не выбрасывается молча — оно помечается, а список строится по доступной части. Так сотрудник видит, что произошло, и не пишет в поддержку «пропали заявки».
Ссылка коллеге с другими полномочиями — тот же механизм с другой стороны. Получатель открывает адрес, приложение читает условия, отбрасывает то, на что нет прав, и показывает остальное с пометкой. Это честнее, чем ошибка доступа на весь экран, и безопаснее, чем тихая подмена фильтра.
Сохранённый выбор фильтров на экране сотрудника
Сохранение состояния — половина задачи. Вторая половина — сделать его заметным, чтобы сотрудник доверял списку. Если фильтр применён, это должно быть видно: строка с активными условиями над таблицей, с возможностью снять любое по отдельности.
Неприменённый ввод показывается иначе — например, поле с текстом и кнопкой «применить», без изменения списка. Разница между «я набрал» и «я отфильтровал» должна читаться с одного взгляда, иначе человек либо переспрашивает, либо ошибается.
Отдельный элемент — индикатор того, что показан сохранённый срез, а не свежий. Условно: «показан фильтр от вчера, 18:40» с кнопкой «сбросить». Это снимает главный страх — что приложение показывает не то, что человек думает.
| Элемент интерфейса | Что сообщает | Когда появляется |
|---|---|---|
| Строка активных условий | Что именно отфильтровано | Фильтр применён |
| Поле с неприменённым вводом | Текст набран, но не действует | Есть ввод без применения |
| Пометка сохранённого среза | Показан прошлый фильтр | Восстановление из хранилища |
| Кнопка сброса | Один шаг к полному списку | Фильтр не пустой |
Тесты, которые ловят потерю контекста
Проверять это вручную по одному сценарию — долго и ненадёжно. Набор тестов стоит зафиксировать как чек-лист и прогонять при каждом изменении списка. Вот минимальный набор, который закрывает основные дыры.
Первый тест: применить фильтр, открыть карточку, нажать «назад» — условия и прокрутка на месте. Второй: применить фильтр, перезагрузить страницу — условия те же. Третий: скопировать адрес, открыть в новой вкладке — условия те же. Четвёртый: удалить последнюю запись в срезе — виден экран пустого состояния со сбросом, а не голая таблица.
Пятый: открыть ссылку под учёткой с урезанными правами — приложение показывает доступное и помечает недоступное. Шестой: открыть сохранённый фильтр старой версии — миграция или явный сброс. Седьмой: набрать текст в поиске, не применять, уйти и вернуться — текст на месте, но помечен как неприменённый.
Эти семь проверок занимают немного времени и отсекают большинство жалоб «список сбрасывается». Их стоит держать рядом с кодом списка, а не в отдельном документе, который никто не открывает.
Практикум: список заявок с фильтром по складу
Возьмём другой пример, чтобы не повторять арифметику возвратов. Условный интегратор ведёт список отгрузок со склада. Фильтр: склад, период, статус отгрузки. Сотрудник отбирает отгрузки конкретного склада за неделю, открывает одну, печатает накладную, возвращается.
Задача — чтобы после возврата он видел тот же склад, ту же неделю и тот же статус, а прокрутка стояла на той же строке. Разложим по слоям: применённый фильтр уходит в адрес; вход в карточку добавляет запись истории; возврат читает состояние и восстанавливает список; локально сохраняется последний срез на случай утреннего открытия.
Дальше — исключения. Если склад закрыли и он пропал из справочника, условие помечается как недоступное, список строится по остальным. Если сотрудника перевели на другой склад, его сохранённый срез корректируется по правам. Если он открыл ссылку коллеги с фильтром по чужому складу — видит доступные склады и пометку о недоступном.
И наконец, интерфейс: строка «склад: Северный · неделя · в работе» над таблицей, кнопка сброса рядом, пометка о восстановленном срезе, если он пришёл из хранилища. Сотрудник в любой момент понимает, что именно он видит.
Что проверить до того, как отдавать в работу
Прежде чем запускать изменения, стоит ответить на несколько вопросов, которые обычно всплывают уже в процессе. Где единственный источник правды для применённого фильтра? Что попадает в адрес, а что категорически нет? Как ведёт себя «назад» после смены фильтра — одна запись или много? Что показывается при пустом результате? Как сверяются условия с правами при открытии чужой ссылки?
Если ответы зафиксированы и совпадают у разработчика и у заказчика, дальше работа идёт по методике, а не по интуиции. Если нет — каждый сценарий будет решаться заново, и список продолжит сбрасываться то тут, то там.
Отдельно про данные в ссылке: правила о том, что можно показывать в адресе и логах, стоит сверить с применимыми внутренними документами и у уполномоченного сотрудника, а не решать на уровне команды. Это не про удобство, а про то, что окажется в чужой истории браузера.
Один шаг проверки
Исходная задача была простой: сотрудник возвращается к списку и не теряет отбор. Решается она не одной функцией, а договорённостью о слоях — адрес, история, локальное хранилище, неприменённый ввод — и честным поведением в исключениях: пустой результат, устаревший фильтр, изменённые права, чужая ссылка.
Ссылка коллеге: фильтр переносится, полномочия — нет
Условный руководитель отправляет коллеге ссылку на список просроченных обращений своего подразделения. Передавать в URL можно согласованные параметры отбора, но не секреты и не полную выгрузку строк. При открытии сервер заново проверяет права получателя. Тот же фильтр может дать другой доступный набор результатов, и это корректно: ссылка описывает запрос, а не передаёт полномочия отправителя.
Если параметр больше не существует или пользователь лишился доступа к подразделению, интерфейс не должен молча расширять выбор на всю компанию. Лучше обозначить неприменимое условие и предложить разрешённый вариант. Для проверки сравните три случая: возврат автора к своему списку, открытие ссылки сотрудником с другими правами и открытие после удаления сохранённого представления. Понятное восстановление контекста включает объяснение изменений, а не только визуально похожую строку фильтров.
Смежный вопрос разобран отдельно: PWA или Telegram Mini App: как выбрать формат приложения для бизнеса.
Источники и границы разбора
Источники и статус проверки на 9 ноября 2026. Первичные документы поясняют указанные механизмы; доступность и границы каждого источника отмечены ниже. Методические рекомендации и условные примеры составляют самостоятельную часть разбора.
- Приложения для бизнеса
Опубликованное направление работы 404ai. Предлагаемая в статье методика не означает, что каждое описанное действие уже доступно без настройки; состав решения согласуется отдельно.
- MDN: History API
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.
- MDN: Web Storage API
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.
- W3C: Tables Tutorial
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.