# Angular / Ionic

Интерфейс расписания с фильтрами, таблицами и редактированием записей. Для публичного показа подготовлен полный синтетический набор данных и мобильные состояния.

Статус: passed

Версия: `71ea9d0d972465a648633a244d1004d2785c8596`. В репозитории есть исходный снимок от 1 мая 2024; начало разработки этим не установлено. Демо: 7 сентября 2026.

## Задача

Оператору нужно быстро находить запись в расписании, видеть её статус и менять поля без потери контекста таблицы.

## Аудитория

Операторы расписаний и пользователи прикладных учётных интерфейсов.

## Личный вклад

- Мобильная оболочка с настоящим viewport, адаптивный экран входа и синхронизация маршрута.

- Стабильный пересчёт таблицы после переходов Ionic.

- Связка Angular, Ionic и табличных компонентов.

- Фильтры, формы, статусы выполнения и мобильное представление.

- Исправление идентификаторов и повторного добавления, изоляция демонстрационного входа и воспроизводимые данные.

## Решения

- Синтетические записи покрывают демонстрируемые поля, а не заменяют таблицу пустым макетом.

- Форма редактирует черновик; отмена не должна менять исходную запись.

- Изменения остаются внутри браузерной сессии; серверный API расписаний в публичное демо не подключён.

## Границы и ограничения

- Демонстрационный вход test / test не является системой аутентификации.

- 180 синтетических лабораторных записей и четыре BCP-примера не являются рабочими данными.

- Нереализованные разделы не включены в маршрут демонстрации. Число добавляемых строк ограничено 500.

## Что попробовать

- Войдите test / test и откройте расписание.

- Отфильтруйте записи, переключите статусы и сравните представления.

- Добавьте запись, проверьте обязательные поля, откройте редактирование и отмените изменение.

- Проверьте мобильный вид и сброс исходного набора.

## Проверки

- Login → schedule

- Filtering and empty state

- Edit cancellation leaves original record unchanged

- Required validation and successful creation

- Independent browser session has original dataset

- Delete selected record

- Reset clears tab session

## Результаты

- Сохранено 13 содержательных кадров фактического интерфейса.

- Дата, сценарий и версия указаны у каждого кадра.

- Отдельного backend-процесса на VPS нет: Nginx раздаёт статику. Ресурсы общего Nginx нельзя честно приписать одному сайту.

- Измерено 6 повторений сценария; медиана 2390.0 мс, максимум 3282 мс. Время включает браузер и HTTPS; методика и ограничения приложены.

## Запуск и эксплуатация

- На компьютере демо работает внутри рамки телефона с same-origin iframe. При ширине окна до 600 px оболочка исчезает, приложение занимает весь экран. После перехода адрес синхронизируется; прямые ссылки и обновление страницы проверены.

- Графики от 7 сентября 01:08–01:11 UTC сняты до визуального обновления. Это контекст статического хостинга предыдущей версии, а не новый замер скорости мобильного интерфейса.

- Рабочий контур прикладной системы предполагает серверный источник расписаний. В публичном контуре используются локальные синтетические данные; это явно обозначено на экране.

- Production-сборка Angular выполняется вне VPS. На сервер передаётся каталог готовых файлов, Nginx отдаёт его по HTTPS. Постоянного Node.js-процесса для этого демо нет.

- Проверять /healthz, прямые маршруты после обновления страницы, вход, сохранение и отмену формы. Для отката переключить current на сохранённый каталог релиза. Данные восстанавливаются из встроенного набора.

- Общие правила эксплуатации: готовые файлы и закреплённые образы собираются вне VPS; секреты не входят в артефакты. Общесерверный docker prune не применяется. Логи backend ограничены ротацией, изменения log options требуют пересоздания контейнера.

- Перед изменением пройти code-map от функции к экрану/API, модулю и данным. После изменения обновить карту и схемы, выполнить связанные сценарии, включая ошибку, повтор и сброс. Источник истины — конкретная версия кода, а не старая диаграмма.

- Откат проверен 2026-09-07T00:59:39.939043+00:00: 20260907-verified → 20260907 → 20260907-verified. После каждого переключения подтверждены HTTPS, readiness и SHA. Это проверка конфигурации и артефактов на одном проверенном SHA; обратная миграция БД не выполнялась.

## Стек и роль

- **Angular 17**: Компоненты страниц, формы, маршрутизация и состояние.
- **Ionic 7**: Навигация, элементы управления, модальные формы и адаптивный интерфейс.
- **SlickGrid**: Табличное представление и операции со строками.

## Code-map

|Функция|Экран / API|Модуль|Данные / проверка|
|---|---|---|---|
|Рамка телефона|Корневой URL / iframe|src/main.ts; src/phone-preview.ts; src/global.scss|DOM viewport; 390/600/768/1024/1440 px|
|Синхронизация адреса|login, schedule, bcp|AppComponent NavigationEnd; phone-preview message listener|same-origin/source checks; refresh QA|
|Демо-вход|login / users/authenticate|login.page; AuthenticationService; fake backend|test/test; sessionStorage; login/reset QA|
|Расписание и фильтры|schedule|schedule.page; table component; table service|180 seed-записей; фильтр/пустое состояние|
|Формы и удаление|schedule / Ionic modal|schedule.page openNew/openEdit/confirm|копия черновика, обязательные поля; cancel/create/delete QA|
|Пункты забора|bcp / меню|bcp page; demo data service|четыре синтетических пункта; навигация QA|
|Сброс|Сбросить свой пример|AppComponent.resetDemo|перезагрузка вкладки, удаление demo login; isolation QA|

## Схемы

- Компоненты опубликованного демо — `diagrams/components.mmd`
- Основной сценарий — `diagrams/scenario.mmd`
- Размещение опубликованной версии — `diagrams/deployment.mmd`

## Индекс изображений

- 01-login: Вход с явно показанными тестовыми данными; 2026-09-07T03:57:03.244Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 02-schedule: Расписание со 180 воспроизводимыми синтетическими записями; 2026-09-07T03:57:04.809Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 03-filtered: Фильтр завершённых исследований; 2026-09-07T03:57:06.138Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 04-empty: Фильтр без совпадений; 2026-09-07T03:57:07.366Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 05-edit-draft: Изолированный черновик редактирования; 2026-09-07T03:57:08.291Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 06-validation: Ошибка обязательных полей; 2026-09-07T03:57:09.677Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 07-create-form: Заполненная форма новой записи; 2026-09-07T03:57:10.273Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 08-created: Новая запись в таблице; 2026-09-07T03:57:11.219Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 09-delete: Подтверждение удаления своей записи; 2026-09-07T03:57:14.514Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 10-collection-points: Синтетические пункты забора; 2026-09-07T03:57:16.452Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 11-mobile-schedule: Мобильное расписание с прокруткой таблицы; 2026-09-07T03:57:18.021Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 12-mobile-form: Мобильная форма Ionic; 2026-09-07T03:57:18.718Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596
- 13-reset: Сброс с возвращением к входу; 2026-09-07T03:57:20.533Z; SHA 71ea9d0d972465a648633a244d1004d2785c8596

## Подробности runtime из репозитория

# Angular / Ionic: мобильное демонстрационное расписание

Демо: https://ionic.komaroff-dev.ru/. Визуальное обновление — 7 сентября 2026.
Исходный снимок репозитория относится к маю 2024; это не доказательство даты начала разработки.

## Работа интерфейса

На компьютере приложение открывается внутри рамки телефона. Это same-origin iframe
с настоящим узким viewport: Ionic рассчитывает меню, таблицу, модальные окна и
media queries по ширине экрана телефона. При 1440 px ширина содержимого — 390 px.
На мобильном экране до 600 px рамка и текстовая колонка скрываются, iframe занимает
всю ширину и динамическую высоту окна. При невысоком окне сохраняется прокрутка.

`main.ts` запускает оболочку только в верхнем окне; внутри iframe выполняется обычный
Angular bootstrap. Маршрут из Router передаётся родителю через postMessage. Родитель
проверяет origin, источник окна и относительный URL. Адрес сохраняется при refresh;
данные демо остаются в пределах вкладки. Внешних iframe или серверов здесь нет.

## Сценарии

Вход test / test → расписание со 180 синтетическими записями → фильтр таблицы →
выбор записи → редактирование или отмена. Можно создать запись с проверкой обязательных
полей, удалить свою запись и открыть четыре демонстрационных пункта забора через меню.
Широкая таблица прокручивается горизонтально внутри приложения. Сброс возвращает
начальное состояние вкладки и экран входа.

Контейнер SlickGrid имеет явный id для autoResize. После завершения перехода Ionic
ionViewDidEnter повторно рассчитывает размеры таблицы, чтобы она не оставалась
нулевой высоты при открытии напрямую или изменении viewport.

Angular 17, Ionic 7 и SlickGrid работают реально. Авторизация и API данных заменены
локальным demo adapter. Лабораторные интеграции не подключены, данные вымышленные;
уведомление об этом видно в основном интерфейсе. Пароль test не является рабочим секретом.

## Code-map

| Функция | Экран / API | Модуль | Данные / проверка |
|---|---|---|---|
| Рамка телефона | Корневой URL / iframe | src/main.ts; src/phone-preview.ts; src/global.scss | DOM viewport; 390/600/768/1024/1440 px |
| Синхронизация адреса | login, schedule, bcp | AppComponent NavigationEnd; phone-preview message listener | same-origin/source checks; refresh QA |
| Демо-вход | login / users/authenticate | login.page; AuthenticationService; fake backend | test/test; sessionStorage; login/reset QA |
| Расписание и фильтры | schedule | schedule.page; table component; table service | 180 seed-записей; фильтр/пустое состояние |
| Формы и удаление | schedule / Ionic modal | schedule.page openNew/openEdit/confirm | копия черновика, обязательные поля; cancel/create/delete QA |
| Пункты забора | bcp / меню | bcp page; demo data service | четыре синтетических пункта; навигация QA |
| Сброс | Сбросить свой пример | AppComponent.resetDemo | перезагрузка вкладки, удаление demo login; isolation QA |

Перед изменением проследить функцию по карте до формы/состояния, после изменения
обновить карту, схемы и кадры, проверить вход, отмену, повтор, чужую вкладку и сброс.

## Сборка и размещение

Воспроизводимая production-сборка выполняется вне VPS через Dockerfile.portfolio:
закреплённый Node 20.20.1, npm ci с package-lock, ng build. На сервер переносятся
только файлы www. Nginx отдаёт index.html для прямых маршрутов и отдельные assets.
Runtime Node.js и новые контейнеры этому демо не нужны.

Исторические предупреждения сборки: CommonJS moment-mini/flatpickr, CSS-селекторы
сторонних таблиц и исходный budget около 2 MB. Они не выдаются за полностью устранённый
технический долг. Обновление проверяет выбранные сценарии, а не весь старый проект.

Ресурсные графики от 7 сентября 01:08–01:11 UTC относятся к предыдущей публикации
до визуального обновления; это контекст общего статического хостинга, не новые замеры
производительности телефона. Метрики не переносятся на новый SHA без этой оговорки.
