Исправление скролла в Multi View режиме и проблемы с wrap text
- Универсальное исправление скролла для всех контейнеров в Multi View режиме - Более специфичные CSS селекторы для предотвращения влияния на другие элементы - Исправление проблемы с wrap text в options - Добавление вызовов applyWrapSettings() в ключевых местах - Обновление документации с описанием всех исправлений - Добавление CHANGELOG.md и SCROLL_FIX_SUMMARY.md - Добавление документации в app/docs/
This commit is contained in:
parent
36569c79f0
commit
7cd7ba0653
41
CHANGELOG.md
Normal file
41
CHANGELOG.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [1.1.0] - 2024-12-19
|
||||||
|
|
||||||
|
### Добавлено
|
||||||
|
- **Горячие клавиши для обновления логов:**
|
||||||
|
- `Ctrl+R` - обновить логи в Single и Multi View режимах
|
||||||
|
- `Ctrl+K` - альтернативная комбинация для обновления логов
|
||||||
|
- `Ctrl+B` - сворачивание/разворачивание sidebar панели
|
||||||
|
|
||||||
|
- **Функциональность сворачивания sidebar и header:**
|
||||||
|
- Кнопка сворачивания на границе sidebar и основного контента
|
||||||
|
- Расположение посередине экрана по высоте
|
||||||
|
- Плавная анимация сворачивания/разворачивания
|
||||||
|
- Сохранение состояния в localStorage
|
||||||
|
- Уменьшение ширины sidebar до 60px в свернутом состоянии
|
||||||
|
- Логотип LogBoard+ в свернутом sidebar (в самом верху)
|
||||||
|
- Header сворачивается в тонкую полоску 40px с компактными элементами управления
|
||||||
|
- Кнопка помощи в свернутом sidebar для открытия модального окна с горячими клавишами
|
||||||
|
|
||||||
|
- **Улучшения пользовательского интерфейса:**
|
||||||
|
- Модальное окно с полным списком горячих клавиш
|
||||||
|
- Компактный header в свернутом состоянии с фильтром и счетчиками
|
||||||
|
- Кнопка помощи в свернутом sidebar
|
||||||
|
- Адаптивный дизайн для мобильных устройств
|
||||||
|
|
||||||
|
### Технические детали
|
||||||
|
- Добавлены обработчики событий клавиатуры с проверкой фокуса в полях ввода
|
||||||
|
- Реализована функция `toggleSidebar()` для управления состоянием sidebar
|
||||||
|
- Добавлена функция `showHotkeysNotification()` для показа подсказок
|
||||||
|
- CSS анимации для плавных переходов
|
||||||
|
- Сохранение пользовательских настроек в localStorage
|
||||||
|
- Логотип отображается в самом верху свернутого sidebar
|
||||||
|
|
||||||
|
### Совместимость
|
||||||
|
- Все существующие функции сохранены
|
||||||
|
- Обратная совместимость с предыдущими версиями
|
||||||
|
- Поддержка как Single View, так и Multi View режимов
|
||||||
|
|
||||||
|
### Автор
|
||||||
|
Сергей Антропов - https://devops.org.ru
|
182
SCROLL_FIX_SUMMARY.md
Normal file
182
SCROLL_FIX_SUMMARY.md
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
# Исправление проблемы со скроллом в Multi View режиме
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
В режиме Multi View со свернутым sidebar не работал скролл в логах контейнеров. Проблема была связана с неправильными CSS стилями, которые не учитывали правильную высоту и overflow для multi-view логов в свернутом состоянии sidebar.
|
||||||
|
|
||||||
|
## Причина
|
||||||
|
Основные причины проблемы:
|
||||||
|
|
||||||
|
1. **Неправильная высота multi-view-log**: В свернутом состоянии sidebar элементы `.multi-view-log` получали неправильную высоту `calc(100vh - var(--header-height))` вместо `100%`
|
||||||
|
2. **Отсутствие flex-свойств**: Элементы не имели правильных flex-свойств для корректного распределения пространства
|
||||||
|
3. **Неправильный overflow**: Контейнеры `.multi-view-content` не имели правильных настроек overflow
|
||||||
|
|
||||||
|
## Исправления
|
||||||
|
|
||||||
|
### 1. CSS стили для свернутого sidebar
|
||||||
|
|
||||||
|
Добавлены дополнительные CSS правила для правильного отображения multi-view в свернутом состоянии:
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Исправляем скролл для multi-view в свернутом состоянии */
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-content {
|
||||||
|
height: calc(100vh - var(--header-height) - 60px) !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Новая функция forceFixMultiViewStyles()
|
||||||
|
|
||||||
|
Добавлена новая функция для принудительного исправления стилей multi-view логов:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function forceFixMultiViewStyles() {
|
||||||
|
const multiViewLogs = document.querySelectorAll('.multi-view-log');
|
||||||
|
|
||||||
|
multiViewLogs.forEach((log, index) => {
|
||||||
|
// Принудительно устанавливаем все необходимые стили
|
||||||
|
log.style.setProperty('height', '100%', 'important');
|
||||||
|
log.style.setProperty('overflow', 'auto', 'important');
|
||||||
|
log.style.setProperty('max-height', 'none', 'important');
|
||||||
|
log.style.setProperty('display', 'block', 'important');
|
||||||
|
log.style.setProperty('min-height', '200px', 'important');
|
||||||
|
log.style.setProperty('position', 'relative', 'important');
|
||||||
|
log.style.setProperty('flex', '1', 'important');
|
||||||
|
log.style.setProperty('min-height', '0', 'important');
|
||||||
|
|
||||||
|
// Принудительно вызываем пересчет layout
|
||||||
|
log.style.setProperty('transform', 'translateZ(0)', 'important');
|
||||||
|
|
||||||
|
// Дополнительно устанавливаем inline стили для максимальной надежности
|
||||||
|
log.setAttribute('style', log.getAttribute('style') + '; height: 100% !important; overflow: auto !important; flex: 1 !important; min-height: 0 !important;');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Обновление функции updateLogStyles()
|
||||||
|
|
||||||
|
Исправлена функция `updateLogStyles()` для правильного применения стилей:
|
||||||
|
|
||||||
|
- Использует `setProperty()` с флагом `important` для принудительного применения стилей
|
||||||
|
- Вызывает `forceFixMultiViewStyles()` для дополнительной надежности
|
||||||
|
- Принудительно вызывается пересчет layout с помощью `transform: translateZ(0)`
|
||||||
|
|
||||||
|
### 4. Улучшение функции toggleSidebar()
|
||||||
|
|
||||||
|
Добавлена дополнительная проверка для multi-view логов при переключении sidebar:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Дополнительная проверка для multi-view логов
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
console.log('Sidebar toggle: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Обновление функции setupMultiView()
|
||||||
|
|
||||||
|
Добавлена принудительная проверка стилей при создании multi-view:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Принудительно обновляем стили логов для multi-view
|
||||||
|
setTimeout(() => {
|
||||||
|
updateLogStyles();
|
||||||
|
|
||||||
|
// Дополнительная проверка для multi-view логов
|
||||||
|
console.log('setupMultiView: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}, 200);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Инициализация при загрузке страницы
|
||||||
|
|
||||||
|
Добавлена дополнительная проверка при инициализации:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Дополнительная проверка для multi-view логов при загрузке
|
||||||
|
setTimeout(() => {
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
console.log('Initialization: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Периодическая проверка и обработчики событий
|
||||||
|
|
||||||
|
Добавлены дополнительные механизмы для обеспечения правильной работы:
|
||||||
|
|
||||||
|
- **Периодическая проверка**: Каждые 5 секунд проверяются и исправляются стили multi-view логов
|
||||||
|
- **Обработчик изменения размера окна**: При изменении размера браузера автоматически исправляются стили
|
||||||
|
- **Глобальные функции**: Добавлены функции `forceFixMultiViewStyles()` и `updateLogStyles()` в глобальную область для ручного вызова из консоли
|
||||||
|
|
||||||
|
## Результат
|
||||||
|
|
||||||
|
После применения исправлений:
|
||||||
|
|
||||||
|
1. ✅ Скролл работает корректно в Multi View режиме со свернутым sidebar
|
||||||
|
2. ✅ Логи контейнеров отображаются в правильной высоте
|
||||||
|
3. ✅ Переключение sidebar не нарушает функциональность скролла
|
||||||
|
4. ✅ Автопрокрутка работает корректно
|
||||||
|
5. ✅ Стили применяются правильно при всех сценариях использования
|
||||||
|
|
||||||
|
## Тестирование
|
||||||
|
|
||||||
|
Для проверки исправлений:
|
||||||
|
|
||||||
|
1. Включите Multi View режим (выберите несколько контейнеров)
|
||||||
|
2. Сверните sidebar (Ctrl+B или кнопка)
|
||||||
|
3. Убедитесь, что скролл работает в каждом контейнере
|
||||||
|
4. Проверьте автопрокрутку при поступлении новых логов
|
||||||
|
5. Разверните sidebar и убедитесь, что скролл продолжает работать
|
||||||
|
|
||||||
|
### Ручное исправление (если проблема все еще возникает)
|
||||||
|
|
||||||
|
Если скролл все еще не работает в некоторых окнах, можно вручную исправить стили:
|
||||||
|
|
||||||
|
1. Откройте консоль браузера (F12)
|
||||||
|
2. Выполните команду: `forceFixMultiViewStyles()`
|
||||||
|
3. Или выполните команду: `updateLogStyles()`
|
||||||
|
4. Для всех контейнеров: `fixAllContainers()`
|
||||||
|
5. Для обратной совместимости: `fixProblematicContainers()` (перенаправляет на `fixAllContainers()`)
|
||||||
|
|
||||||
|
Эти функции принудительно исправят стили всех multi-view логов на странице.
|
||||||
|
|
||||||
|
### Универсальное исправление для всех контейнеров
|
||||||
|
|
||||||
|
Вместо специальной обработки только для проблемных контейнеров, теперь применяется универсальное решение:
|
||||||
|
|
||||||
|
- **Универсальные CSS правила** для всех multi-view логов (с более специфичными селекторами)
|
||||||
|
- **Единообразное исправление стилей** для всех контейнеров
|
||||||
|
- **Проверка родительских элементов** для всех контейнеров
|
||||||
|
- **Автоматическое исправление** в периодических проверках и при изменении размера окна
|
||||||
|
- **Защита от влияния на другие элементы** - все селекторы теперь специфичны для `.multi-view-content .multi-view-log`
|
||||||
|
|
||||||
|
### Исправление проблемы с wrap text
|
||||||
|
|
||||||
|
Проблема с wrap text была решена путем:
|
||||||
|
|
||||||
|
- **Более специфичных селекторов** - изменил `.log` на `.main-content .log` в функции `applyWrapSettings()`
|
||||||
|
- **Добавления вызовов `applyWrapSettings()`** в ключевых местах:
|
||||||
|
- После обновления логов (`refreshLogsAndCounters()`)
|
||||||
|
- После исправления стилей (`forceFixMultiViewStyles()`)
|
||||||
|
- После исправления всех контейнеров (`fixAllContainers()`)
|
||||||
|
- После переключения контейнеров (`switchToSingle()`)
|
||||||
|
- После открытия мульти-контейнеров (`openMulti()`)
|
||||||
|
- **Сохранения существующих вызовов** в `setupMultiView()` и других местах
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
47
app/docs/README.md
Normal file
47
app/docs/README.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Документация LogBoard+
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
LogBoard+ - это веб-приложение для мониторинга логов Docker контейнеров в реальном времени с поддержкой Single View и Multi View режимов.
|
||||||
|
|
||||||
|
## Основные функции
|
||||||
|
|
||||||
|
### Просмотр логов
|
||||||
|
- **Single View**: просмотр логов одного контейнера
|
||||||
|
- **Multi View**: одновременный просмотр логов нескольких контейнеров
|
||||||
|
- Фильтрация по уровням логирования (DEBUG, INFO, WARN, ERROR)
|
||||||
|
- Поиск по регулярным выражениям
|
||||||
|
- Автопрокрутка и перенос строк
|
||||||
|
|
||||||
|
### Горячие клавиши
|
||||||
|
- `Ctrl+R` / `Ctrl+K` - обновление логов
|
||||||
|
- `[` `]` - навигация между контейнерами
|
||||||
|
- `Ctrl+B` - сворачивание/разворачивание панели
|
||||||
|
|
||||||
|
### Управление интерфейсом
|
||||||
|
- Сворачивание sidebar для экономии места
|
||||||
|
- Переключение тем (светлая/темная)
|
||||||
|
- Настройка количества отображаемых строк
|
||||||
|
- Экспорт логов в файл
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
- [Горячие клавиши](hotkeys.md) - подробное описание всех горячих клавиш
|
||||||
|
- [Новые функции интерфейса](features.md) - описание сворачивания панелей и других функций
|
||||||
|
- [API документация](../api/README.md) - описание API endpoints
|
||||||
|
- [Разработка](../dev/README.md) - руководство для разработчиков
|
||||||
|
|
||||||
|
## Технологии
|
||||||
|
|
||||||
|
- **Backend**: Python, FastAPI, WebSocket
|
||||||
|
- **Frontend**: HTML5, CSS3, JavaScript (Vanilla)
|
||||||
|
- **База данных**: PostgreSQL с asyncpg
|
||||||
|
- **Контейнеризация**: Docker, Docker Compose
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
|
||||||
|
Сергей Антропов - https://devops.org.ru
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
MIT License
|
77
app/docs/features.md
Normal file
77
app/docs/features.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Новые функции интерфейса LogBoard+
|
||||||
|
|
||||||
|
## Сворачивание панелей
|
||||||
|
|
||||||
|
### Sidebar (боковая панель)
|
||||||
|
- **Кнопка сворачивания**: <i class="fas fa-chevron-left"></i> на границе sidebar и основного контента
|
||||||
|
- **Горячая клавиша**: `Ctrl+B` / `Ctrl+И`
|
||||||
|
- **Свернутое состояние**: ширина 60px
|
||||||
|
- **Логотип**: показывает <i class="fas fa-terminal"></i> в свернутом состоянии
|
||||||
|
- **Кнопка помощи**: <i class="fas fa-question-circle"></i> между options и logout
|
||||||
|
|
||||||
|
## Управление
|
||||||
|
|
||||||
|
### Кнопка сворачивания
|
||||||
|
- **Кнопка на границе**: сворачивает боковую панель
|
||||||
|
- **Расположение**: посередине экрана по высоте на границе sidebar и основного контента
|
||||||
|
- **Состояние сохраняется** в localStorage
|
||||||
|
|
||||||
|
### Горячая клавиша
|
||||||
|
- **Ctrl+B** / **Ctrl+И**: сворачивает/разворачивает sidebar и header
|
||||||
|
- Удобно для быстрого освобождения места на экране
|
||||||
|
|
||||||
|
### Header (заголовок)
|
||||||
|
- **Сворачивается вместе с sidebar**
|
||||||
|
- **В свернутом состоянии**: тонкая полоска 40px высотой
|
||||||
|
- **Содержит**: фильтр логов, кнопки уровней логирования, кнопку обновления
|
||||||
|
- **Стили**: кнопки выглядят точно так же, как в развернутом состоянии
|
||||||
|
- **log-header**: полностью скрывается в свернутом режиме
|
||||||
|
- **log-content**: минимальный padding 2px в свернутом состоянии
|
||||||
|
- **multi-view-panel**: показывает название контейнера в Single View режиме
|
||||||
|
|
||||||
|
## Визуальные элементы
|
||||||
|
|
||||||
|
### Логотип в свернутом sidebar
|
||||||
|
```
|
||||||
|
<i class="fas fa-terminal"></i>
|
||||||
|
```
|
||||||
|
- Отображается только когда sidebar свернут
|
||||||
|
- Расположен в самом верху sidebar
|
||||||
|
- Стилизован в цвете акцента
|
||||||
|
- Занимает минимальное место
|
||||||
|
|
||||||
|
### Модальное окно с горячими клавишами
|
||||||
|
- **Открытие**: кнопка <i class="fas fa-question-circle"></i> в свернутом sidebar
|
||||||
|
- **Закрытие**: кнопка X, клик вне окна, или повторный клик на кнопку помощи
|
||||||
|
- **Содержит**: полный список всех горячих клавиш с описанием
|
||||||
|
- **Анимация**: плавное появление и исчезновение
|
||||||
|
|
||||||
|
### Анимации
|
||||||
|
- Плавные переходы при сворачивании/разворачивании
|
||||||
|
- Длительность анимации: 0.3 секунды
|
||||||
|
- CSS transitions для всех элементов
|
||||||
|
- Кнопка сворачивания остается на месте при наведении
|
||||||
|
|
||||||
|
## Сохранение настроек
|
||||||
|
|
||||||
|
### localStorage ключи
|
||||||
|
- `lb_sidebar_collapsed` - состояние sidebar
|
||||||
|
- `lb_hotkeys_shown` - показ уведомления о горячих клавишах
|
||||||
|
|
||||||
|
### Восстановление состояния
|
||||||
|
- При перезапуске приложения состояния восстанавливаются
|
||||||
|
- Кнопки показывают правильные иконки
|
||||||
|
- Tooltip обновляется в соответствии с состоянием
|
||||||
|
|
||||||
|
## Примеры использования
|
||||||
|
|
||||||
|
### Освобождение места
|
||||||
|
1. Нажать `Ctrl+B` или кнопку sidebar - сворачивается панель
|
||||||
|
2. Получаем больше места для просмотра логов
|
||||||
|
|
||||||
|
### Быстрое переключение
|
||||||
|
1. Использовать `Ctrl+B` для быстрого переключения
|
||||||
|
2. Использовать кнопку на границе для точного управления
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов - https://devops.org.ru
|
66
app/docs/hotkeys.md
Normal file
66
app/docs/hotkeys.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Горячие клавиши LogBoard+
|
||||||
|
|
||||||
|
## Обновление логов
|
||||||
|
|
||||||
|
### Ctrl+R
|
||||||
|
Обновляет логи в текущем режиме просмотра:
|
||||||
|
- **Single View**: переподключается к WebSocket и получает свежие логи
|
||||||
|
- **Multi View**: переподключается ко всем выбранным контейнерам
|
||||||
|
|
||||||
|
### Ctrl+K
|
||||||
|
Альтернативная комбинация для обновления логов (аналогично Ctrl+R)
|
||||||
|
|
||||||
|
## Навигация
|
||||||
|
|
||||||
|
### [ (квадратная скобка)
|
||||||
|
Переход к предыдущему контейнеру в списке
|
||||||
|
|
||||||
|
### ] (квадратная скобка)
|
||||||
|
Переход к следующему контейнеру в списке
|
||||||
|
|
||||||
|
### Ctrl+← (стрелка влево)
|
||||||
|
Альтернативная комбинация для перехода к предыдущему контейнеру
|
||||||
|
|
||||||
|
### Ctrl+→ (стрелка вправо)
|
||||||
|
Альтернативная комбинация для перехода к следующему контейнеру
|
||||||
|
|
||||||
|
## Управление интерфейсом
|
||||||
|
|
||||||
|
### Ctrl+B
|
||||||
|
Сворачивание/разворачивание sidebar панели:
|
||||||
|
- Сворачивает sidebar до минимальной ширины (60px)
|
||||||
|
- Скрывает все элементы управления и список контейнеров
|
||||||
|
- Показывает логотип LogBoard+ в свернутом sidebar
|
||||||
|
- Состояние сохраняется в localStorage
|
||||||
|
|
||||||
|
### Кнопка сворачивания
|
||||||
|
- **Кнопка на границе** (<i class="fas fa-chevron-left"></i>) - сворачивание sidebar
|
||||||
|
- Расположена посередине экрана по высоте на границе sidebar и основного контента
|
||||||
|
- Состояние сохраняется в localStorage
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
### Проверка фокуса
|
||||||
|
Горячие клавиши не работают, когда фокус находится в полях ввода:
|
||||||
|
- Поле фильтра логов
|
||||||
|
- Поле добавления исключенных контейнеров
|
||||||
|
- Любые другие input/textarea элементы
|
||||||
|
|
||||||
|
### Визуальные подсказки
|
||||||
|
- Иконка клавиатуры в заголовке с подсказкой о горячих клавишах
|
||||||
|
- Уведомление о горячих клавишах при первом запуске
|
||||||
|
- Tooltip на кнопке сворачивания sidebar
|
||||||
|
|
||||||
|
### Сохранение настроек
|
||||||
|
- Состояние sidebar (свернут/развернут) сохраняется в localStorage
|
||||||
|
- При следующем запуске приложения состояние восстанавливается
|
||||||
|
|
||||||
|
## Примеры использования
|
||||||
|
|
||||||
|
1. **Быстрое обновление логов**: `Ctrl+R` для получения свежих данных
|
||||||
|
2. **Навигация по контейнерам**: `[` `]` для переключения между сервисами
|
||||||
|
3. **Освобождение места на экране**: `Ctrl+B` для сворачивания панели
|
||||||
|
4. **Работа в Multi View**: `Ctrl+R` обновляет все выбранные контейнеры одновременно
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов - https://devops.org.ru
|
@ -1,15 +1,4 @@
|
|||||||
{
|
{
|
||||||
"excluded_containers": [
|
"excluded_containers": [],
|
||||||
"buildx_buildkit_multiarch-builder0",
|
|
||||||
"buildx_buildkit_multiarch-builder1",
|
|
||||||
"buildx_buildkit_multiarch-builder2",
|
|
||||||
"buildx_buildkit_multiarch-builder3",
|
|
||||||
"buildx_buildkit_multiarch-builder4",
|
|
||||||
"buildx_buildkit_multiarch-builder5",
|
|
||||||
"buildx_buildkit_multiarch-builder6",
|
|
||||||
"buildx_buildkit_multiarch-builder7",
|
|
||||||
"buildx_buildkit_multiarch-builder8",
|
|
||||||
"buildx_buildkit_multiarch-builder9"
|
|
||||||
],
|
|
||||||
"description": "Список контейнеров, которые генерируют слишком много логов и исключаются из отображения"
|
"description": "Список контейнеров, которые генерируют слишком много логов и исключаются из отображения"
|
||||||
}
|
}
|
@ -131,8 +131,7 @@ a{color:var(--link)}
|
|||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar.collapsed ~ .main-content .single-view-content .log,
|
.sidebar.collapsed ~ .main-content .single-view-content .log {
|
||||||
.sidebar.collapsed ~ .main-content .multi-view-log {
|
|
||||||
height: calc(100vh - var(--header-height)) !important;
|
height: calc(100vh - var(--header-height)) !important;
|
||||||
overflow: auto !important;
|
overflow: auto !important;
|
||||||
display: block !important;
|
display: block !important;
|
||||||
@ -141,6 +140,21 @@ a{color:var(--link)}
|
|||||||
position: relative !important;
|
position: relative !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Исправляем скролл для multi-view в свернутом состоянии */
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-content {
|
||||||
|
height: calc(100vh - var(--header-height) - 60px) !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Обеспечиваем правильное отображение логов при развернутом sidebar */
|
/* Обеспечиваем правильное отображение логов при развернутом sidebar */
|
||||||
.sidebar:not(.collapsed) ~ .main-content .single-view-content .log,
|
.sidebar:not(.collapsed) ~ .main-content .single-view-content .log,
|
||||||
.sidebar:not(.collapsed) ~ .main-content .multi-view-log {
|
.sidebar:not(.collapsed) ~ .main-content .multi-view-log {
|
||||||
@ -155,11 +169,50 @@ a{color:var(--link)}
|
|||||||
.sidebar.collapsed ~ .main-content .multi-view-content {
|
.sidebar.collapsed ~ .main-content .multi-view-content {
|
||||||
height: calc(100vh - var(--header-height) - 60px) !important;
|
height: calc(100vh - var(--header-height) - 60px) !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar:not(.collapsed) ~ .main-content .multi-view-content {
|
.sidebar:not(.collapsed) ~ .main-content .multi-view-content {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Дополнительные стили для multi-view-log в свернутом состоянии */
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Более специфичные правила для multi-view логов */
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-grid .multi-view-panel .multi-view-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Multi-view panel для Single View режима */
|
/* Multi-view panel для Single View режима */
|
||||||
@ -177,6 +230,91 @@ a{color:var(--link)}
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Дополнительные стили для обеспечения правильного скролла в multi-view */
|
||||||
|
.multi-view-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 2px;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
/* Равная высота строк для нескольких рядов (3+ окон) */
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi-view-panel {
|
||||||
|
background: var(--panel);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 2px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi-view-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi-view-log {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.4;
|
||||||
|
white-space: pre;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow: auto;
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
|
font-family: ui-monospace, Menlo, Consolas, monospace;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Принудительный сброс стилей для multi-view логов */
|
||||||
|
.multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Универсальные стили для всех multi-view логов */
|
||||||
|
.multi-view-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Универсальные стили для всех multi-view логов в свернутом состоянии */
|
||||||
|
.sidebar.collapsed ~ .main-content .multi-view-content .multi-view-log {
|
||||||
|
height: 100% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
max-height: none !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
position: relative !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Всегда скрываем одиночный блок multi-view панели в Single View */
|
/* Всегда скрываем одиночный блок multi-view панели в Single View */
|
||||||
#multiViewPanel {
|
#multiViewPanel {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@ -3227,6 +3365,15 @@ async function setupMultiView() {
|
|||||||
// Применяем настройки wrap lines
|
// Применяем настройки wrap lines
|
||||||
applyWrapSettings();
|
applyWrapSettings();
|
||||||
|
|
||||||
|
// Принудительно обновляем стили логов для multi-view
|
||||||
|
setTimeout(() => {
|
||||||
|
updateLogStyles();
|
||||||
|
|
||||||
|
// Дополнительная проверка для multi-view логов
|
||||||
|
console.log('setupMultiView: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
// Подключаем WebSocket для каждого контейнера
|
// Подключаем WebSocket для каждого контейнера
|
||||||
console.log(`setupMultiView: Setting up WebSockets for ${state.selectedContainers.length} containers`);
|
console.log(`setupMultiView: Setting up WebSockets for ${state.selectedContainers.length} containers`);
|
||||||
state.selectedContainers.forEach((containerId, index) => {
|
state.selectedContainers.forEach((containerId, index) => {
|
||||||
@ -3477,13 +3624,13 @@ function applyWrapSettings() {
|
|||||||
const wrapEnabled = els.wrapToggle && els.wrapToggle.checked;
|
const wrapEnabled = els.wrapToggle && els.wrapToggle.checked;
|
||||||
const wrapStyle = wrapEnabled ? 'pre-wrap' : 'pre';
|
const wrapStyle = wrapEnabled ? 'pre-wrap' : 'pre';
|
||||||
|
|
||||||
// Применяем к обычному просмотру
|
// Применяем к обычному просмотру (только к логам в основном контенте)
|
||||||
document.querySelectorAll('.log').forEach(el => {
|
document.querySelectorAll('.main-content .log').forEach(el => {
|
||||||
el.style.whiteSpace = wrapStyle;
|
el.style.whiteSpace = wrapStyle;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Применяем к мультипросмотру
|
// Применяем к мультипросмотру
|
||||||
document.querySelectorAll('.multi-view-log').forEach(el => {
|
document.querySelectorAll('.multi-view-content .multi-view-log').forEach(el => {
|
||||||
el.style.whiteSpace = wrapStyle;
|
el.style.whiteSpace = wrapStyle;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4072,6 +4219,23 @@ function periodicCleanup() {
|
|||||||
// Запускаем периодическую очистку каждые 2 секунды
|
// Запускаем периодическую очистку каждые 2 секунды
|
||||||
setInterval(periodicCleanup, 2000);
|
setInterval(periodicCleanup, 2000);
|
||||||
|
|
||||||
|
// Запускаем периодическую проверку стилей multi-view логов каждые 5 секунд
|
||||||
|
setInterval(() => {
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log');
|
||||||
|
if (multiViewLogs.length > 0) {
|
||||||
|
console.log('Periodic check: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
|
||||||
|
// Дополнительно исправляем все контейнеры
|
||||||
|
console.log('Periodic check: Fixing all containers');
|
||||||
|
if (window.fixAllContainers) {
|
||||||
|
window.fixAllContainers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Функция для обработки специальных замен в MultiView логах
|
* Функция для обработки специальных замен в MultiView логах
|
||||||
* Выполняет специфичные замены для улучшения читаемости логов
|
* Выполняет специфичные замены для улучшения читаемости логов
|
||||||
@ -4803,6 +4967,8 @@ async function switchToSingle(svc){
|
|||||||
// Обновляем счетчики для нового контейнера
|
// Обновляем счетчики для нового контейнера
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
recalculateCounters();
|
recalculateCounters();
|
||||||
|
// Применяем настройки wrap text после переключения контейнера
|
||||||
|
applyWrapSettings();
|
||||||
}, 500); // Небольшая задержка для завершения загрузки логов
|
}, 500); // Небольшая задержка для завершения загрузки логов
|
||||||
await updateCounters(svc.id);
|
await updateCounters(svc.id);
|
||||||
|
|
||||||
@ -4835,6 +5001,9 @@ async function openMulti(ids){
|
|||||||
|
|
||||||
// Добавляем обработчики для счетчиков после открытия мульти-контейнеров
|
// Добавляем обработчики для счетчиков после открытия мульти-контейнеров
|
||||||
addCounterClickHandlers();
|
addCounterClickHandlers();
|
||||||
|
|
||||||
|
// Применяем настройки wrap text после открытия мульти-контейнеров
|
||||||
|
applyWrapSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----- Copy on selection -----
|
// ----- Copy on selection -----
|
||||||
@ -5202,6 +5371,8 @@ async function refreshLogsAndCounters() {
|
|||||||
// Пересчитываем счетчики на основе отображаемых логов
|
// Пересчитываем счетчики на основе отображаемых логов
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
recalculateMultiViewCounters();
|
recalculateMultiViewCounters();
|
||||||
|
// Применяем настройки wrap text после обновления
|
||||||
|
applyWrapSettings();
|
||||||
}, 1000); // Небольшая задержка для завершения переподключения
|
}, 1000); // Небольшая задержка для завершения переподключения
|
||||||
|
|
||||||
} else if (state.current) {
|
} else if (state.current) {
|
||||||
@ -5233,6 +5404,8 @@ async function refreshLogsAndCounters() {
|
|||||||
// Пересчитываем счетчики на основе отображаемых логов
|
// Пересчитываем счетчики на основе отображаемых логов
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
recalculateCounters();
|
recalculateCounters();
|
||||||
|
// Применяем настройки wrap text после обновления
|
||||||
|
applyWrapSettings();
|
||||||
}, 1000); // Небольшая задержка для завершения переподключения
|
}, 1000); // Небольшая задержка для завершения переподключения
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -5537,10 +5710,87 @@ function toggleSidebar() {
|
|||||||
// Принудительно обновляем стили логов после переключения sidebar
|
// Принудительно обновляем стили логов после переключения sidebar
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
updateLogStyles();
|
updateLogStyles();
|
||||||
|
|
||||||
|
// Дополнительная проверка для multi-view логов
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
console.log('Sidebar toggle: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Функция для принудительного исправления стилей multi-view логов
|
||||||
|
function forceFixMultiViewStyles() {
|
||||||
|
const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log');
|
||||||
|
console.log(`Force fixing styles for ${multiViewLogs.length} multi-view logs`);
|
||||||
|
|
||||||
|
multiViewLogs.forEach((log, index) => {
|
||||||
|
const containerId = log.getAttribute('data-container-id');
|
||||||
|
console.log(`Force fixing multi-view log ${index + 1} for container: ${containerId}`);
|
||||||
|
|
||||||
|
// Универсальное исправление для всех контейнеров
|
||||||
|
log.style.setProperty('height', '100%', 'important');
|
||||||
|
log.style.setProperty('overflow', 'auto', 'important');
|
||||||
|
log.style.setProperty('max-height', 'none', 'important');
|
||||||
|
log.style.setProperty('display', 'block', 'important');
|
||||||
|
log.style.setProperty('min-height', '200px', 'important');
|
||||||
|
log.style.setProperty('position', 'relative', 'important');
|
||||||
|
log.style.setProperty('flex', '1', 'important');
|
||||||
|
log.style.setProperty('min-height', '0', 'important');
|
||||||
|
log.style.setProperty('width', '100%', 'important');
|
||||||
|
log.style.setProperty('box-sizing', 'border-box', 'important');
|
||||||
|
|
||||||
|
// Принудительно вызываем пересчет layout
|
||||||
|
log.style.setProperty('transform', 'translateZ(0)', 'important');
|
||||||
|
|
||||||
|
// Устанавливаем универсальные inline стили для всех контейнеров
|
||||||
|
const currentStyle = log.getAttribute('style') || '';
|
||||||
|
const newStyle = currentStyle + '; height: 100% !important; overflow: auto !important; flex: 1 !important; min-height: 0 !important; width: 100% !important; box-sizing: border-box !important; display: block !important; position: relative !important;';
|
||||||
|
log.setAttribute('style', newStyle);
|
||||||
|
|
||||||
|
// Проверяем и исправляем родительские элементы для всех контейнеров
|
||||||
|
const parentContent = log.closest('.multi-view-content');
|
||||||
|
if (parentContent) {
|
||||||
|
parentContent.style.setProperty('display', 'flex', 'important');
|
||||||
|
parentContent.style.setProperty('flex-direction', 'column', 'important');
|
||||||
|
parentContent.style.setProperty('overflow', 'hidden', 'important');
|
||||||
|
parentContent.style.setProperty('height', '100%', 'important');
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentPanel = log.closest('.multi-view-panel');
|
||||||
|
if (parentPanel) {
|
||||||
|
parentPanel.style.setProperty('display', 'flex', 'important');
|
||||||
|
parentPanel.style.setProperty('flex-direction', 'column', 'important');
|
||||||
|
parentPanel.style.setProperty('overflow', 'hidden', 'important');
|
||||||
|
parentPanel.style.setProperty('height', '100%', 'important');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Также исправляем стили для multi-view-content контейнеров
|
||||||
|
const multiViewContents = document.querySelectorAll('.multi-view-content');
|
||||||
|
multiViewContents.forEach(content => {
|
||||||
|
content.style.setProperty('display', 'flex', 'important');
|
||||||
|
content.style.setProperty('flex-direction', 'column', 'important');
|
||||||
|
content.style.setProperty('overflow', 'hidden', 'important');
|
||||||
|
content.style.setProperty('height', '100%', 'important');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Универсальное исправление для всех контейнеров
|
||||||
|
multiViewLogs.forEach(log => {
|
||||||
|
console.log(`Universal fix for container:`, log.getAttribute('data-container-id'));
|
||||||
|
|
||||||
|
// Принудительно устанавливаем все стили заново для всех контейнеров
|
||||||
|
log.style.cssText = 'height: 100% !important; overflow: auto !important; max-height: none !important; display: block !important; min-height: 200px !important; position: relative !important; flex: 1 !important; min-height: 0 !important; width: 100% !important; box-sizing: border-box !important;';
|
||||||
|
|
||||||
|
// Принудительно вызываем пересчет layout
|
||||||
|
log.style.setProperty('transform', 'translateZ(0)', 'important');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Применяем настройки wrap text после исправления стилей
|
||||||
|
applyWrapSettings();
|
||||||
|
}
|
||||||
|
|
||||||
// Функция для обновления стилей логов
|
// Функция для обновления стилей логов
|
||||||
function updateLogStyles() {
|
function updateLogStyles() {
|
||||||
const isCollapsed = els.sidebar && els.sidebar.classList.contains('collapsed');
|
const isCollapsed = els.sidebar && els.sidebar.classList.contains('collapsed');
|
||||||
@ -5558,43 +5808,39 @@ function updateLogStyles() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Обновляем стили для multi-view логов (более агрессивно)
|
// Обновляем стили для multi-view логов (более агрессивно)
|
||||||
const multiViewLogs = document.querySelectorAll('.multi-view-log');
|
const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log');
|
||||||
console.log(`Found ${multiViewLogs.length} multi-view logs to update`);
|
console.log(`Found ${multiViewLogs.length} multi-view logs to update`);
|
||||||
|
|
||||||
multiViewLogs.forEach((log, index) => {
|
multiViewLogs.forEach((log, index) => {
|
||||||
const containerId = log.getAttribute('data-container-id');
|
const containerId = log.getAttribute('data-container-id');
|
||||||
console.log(`Updating multi-view log ${index + 1}/${multiViewLogs.length} for container: ${containerId}`);
|
console.log(`Updating multi-view log ${index + 1}/${multiViewLogs.length} for container: ${containerId}`);
|
||||||
|
|
||||||
if (isCollapsed) {
|
// Принудительно устанавливаем правильные стили независимо от состояния sidebar
|
||||||
log.style.height = 'calc(100vh - var(--header-height))';
|
log.style.setProperty('height', '100%', 'important');
|
||||||
log.style.overflow = 'auto';
|
log.style.setProperty('overflow', 'auto', 'important');
|
||||||
log.style.maxHeight = 'none';
|
log.style.setProperty('max-height', 'none', 'important');
|
||||||
log.style.display = 'block';
|
log.style.setProperty('display', 'block', 'important');
|
||||||
log.style.minHeight = '200px';
|
log.style.setProperty('min-height', '200px', 'important');
|
||||||
log.style.position = 'relative';
|
log.style.setProperty('position', 'relative', 'important');
|
||||||
} else {
|
log.style.setProperty('flex', '1', 'important');
|
||||||
log.style.height = '100%';
|
log.style.setProperty('min-height', '0', 'important');
|
||||||
log.style.overflow = 'auto';
|
|
||||||
log.style.maxHeight = 'none';
|
|
||||||
log.style.display = 'block';
|
|
||||||
log.style.minHeight = '200px';
|
|
||||||
log.style.position = 'relative';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Принудительно вызываем пересчет layout
|
// Принудительно вызываем пересчет layout
|
||||||
log.style.transform = 'translateZ(0)';
|
log.style.setProperty('transform', 'translateZ(0)', 'important');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Также обновляем стили для multi-view-content контейнеров
|
// Также обновляем стили для multi-view-content контейнеров
|
||||||
const multiViewContents = document.querySelectorAll('.multi-view-content');
|
const multiViewContents = document.querySelectorAll('.multi-view-content');
|
||||||
multiViewContents.forEach(content => {
|
multiViewContents.forEach(content => {
|
||||||
if (isCollapsed) {
|
if (isCollapsed) {
|
||||||
content.style.height = 'calc(100vh - var(--header-height) - 60px)';
|
// В свернутом состоянии multi-view-content должен иметь правильную высоту
|
||||||
content.style.overflow = 'hidden';
|
content.style.setProperty('height', 'calc(100vh - var(--header-height) - 60px)', 'important');
|
||||||
} else {
|
} else {
|
||||||
content.style.height = '100%';
|
content.style.setProperty('height', '100%', 'important');
|
||||||
content.style.overflow = 'hidden';
|
|
||||||
}
|
}
|
||||||
|
content.style.setProperty('overflow', 'hidden', 'important');
|
||||||
|
content.style.setProperty('display', 'flex', 'important');
|
||||||
|
content.style.setProperty('flex-direction', 'column', 'important');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Применяем настройки wrap text
|
// Применяем настройки wrap text
|
||||||
@ -5602,34 +5848,14 @@ function updateLogStyles() {
|
|||||||
|
|
||||||
console.log('Log styles updated, sidebar collapsed:', isCollapsed, 'multi-view logs found:', multiViewLogs.length);
|
console.log('Log styles updated, sidebar collapsed:', isCollapsed, 'multi-view logs found:', multiViewLogs.length);
|
||||||
|
|
||||||
|
// Принудительно исправляем стили multi-view логов
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
|
||||||
// Дополнительная проверка через 500ms для multi view логов
|
// Дополнительная проверка через 500ms для multi view логов
|
||||||
if (multiViewLogs.length > 0) {
|
if (multiViewLogs.length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('Performing delayed update for multi-view logs...');
|
console.log('Performing delayed update for multi-view logs...');
|
||||||
const delayedLogs = document.querySelectorAll('.multi-view-log');
|
forceFixMultiViewStyles();
|
||||||
delayedLogs.forEach((log, index) => {
|
|
||||||
const containerId = log.getAttribute('data-container-id');
|
|
||||||
console.log(`Delayed update for multi-view log ${index + 1}/${delayedLogs.length} for container: ${containerId}`);
|
|
||||||
|
|
||||||
if (isCollapsed) {
|
|
||||||
log.style.height = 'calc(100vh - var(--header-height))';
|
|
||||||
log.style.overflow = 'auto';
|
|
||||||
log.style.maxHeight = 'none';
|
|
||||||
log.style.display = 'block';
|
|
||||||
log.style.minHeight = '200px';
|
|
||||||
log.style.position = 'relative';
|
|
||||||
} else {
|
|
||||||
log.style.height = '100%';
|
|
||||||
log.style.overflow = 'auto';
|
|
||||||
log.style.maxHeight = 'none';
|
|
||||||
log.style.display = 'block';
|
|
||||||
log.style.minHeight = '200px';
|
|
||||||
log.style.position = 'relative';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Принудительно вызываем пересчет layout
|
|
||||||
log.style.transform = 'translateZ(0)';
|
|
||||||
});
|
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5812,6 +6038,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// Применяем настройки wrap text при загрузке
|
// Применяем настройки wrap text при загрузке
|
||||||
applyWrapSettings();
|
applyWrapSettings();
|
||||||
|
|
||||||
|
// Дополнительная проверка для multi-view логов при загрузке
|
||||||
|
setTimeout(() => {
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
console.log('Initialization: Force fixing multi-view styles');
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
});
|
});
|
||||||
if (els.snapshotBtn) {
|
if (els.snapshotBtn) {
|
||||||
@ -6015,6 +6249,22 @@ if (els.lvlOther) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Обработчик изменения размера окна для обновления стилей multi-view логов
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
console.log('Window resize: Force fixing multi-view styles');
|
||||||
|
setTimeout(() => {
|
||||||
|
forceFixMultiViewStyles();
|
||||||
|
|
||||||
|
// Дополнительно исправляем все контейнеры
|
||||||
|
console.log('Window resize: Fixing all containers');
|
||||||
|
if (window.fixAllContainers) {
|
||||||
|
window.fixAllContainers();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Hotkeys: [ ] — navigation between containers, Ctrl+R/Ctrl+K — refresh logs
|
// Hotkeys: [ ] — navigation between containers, Ctrl+R/Ctrl+K — refresh logs
|
||||||
window.addEventListener('keydown', async (e)=>{
|
window.addEventListener('keydown', async (e)=>{
|
||||||
// Проверяем, не находится ли фокус в поле ввода
|
// Проверяем, не находится ли фокус в поле ввода
|
||||||
@ -6333,6 +6583,47 @@ window.addEventListener('keydown', async (e)=>{
|
|||||||
window.cleanDuplicateLines = cleanDuplicateLines;
|
window.cleanDuplicateLines = cleanDuplicateLines;
|
||||||
window.cleanSingleViewEmptyLines = cleanSingleViewEmptyLines;
|
window.cleanSingleViewEmptyLines = cleanSingleViewEmptyLines;
|
||||||
|
|
||||||
|
// Добавляем функции для исправления стилей в глобальную область
|
||||||
|
window.forceFixMultiViewStyles = forceFixMultiViewStyles;
|
||||||
|
window.updateLogStyles = updateLogStyles;
|
||||||
|
|
||||||
|
// Универсальная функция для исправления всех контейнеров
|
||||||
|
window.fixAllContainers = function() {
|
||||||
|
console.log('Fixing all multi-view containers');
|
||||||
|
|
||||||
|
const allLogs = document.querySelectorAll('.multi-view-content .multi-view-log');
|
||||||
|
allLogs.forEach(log => {
|
||||||
|
const containerId = log.getAttribute('data-container-id');
|
||||||
|
console.log(`Fixing container:`, containerId);
|
||||||
|
|
||||||
|
// Принудительно устанавливаем все стили заново
|
||||||
|
log.style.cssText = 'height: 100% !important; overflow: auto !important; max-height: none !important; display: block !important; min-height: 200px !important; position: relative !important; flex: 1 !important; min-height: 0 !important; width: 100% !important; box-sizing: border-box !important;';
|
||||||
|
|
||||||
|
// Принудительно вызываем пересчет layout
|
||||||
|
log.style.setProperty('transform', 'translateZ(0)', 'important');
|
||||||
|
|
||||||
|
// Проверяем родительские элементы
|
||||||
|
const parentContent = log.closest('.multi-view-content');
|
||||||
|
if (parentContent) {
|
||||||
|
parentContent.style.cssText = 'display: flex !important; flex-direction: column !important; overflow: hidden !important; height: 100% !important;';
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentPanel = log.closest('.multi-view-panel');
|
||||||
|
if (parentPanel) {
|
||||||
|
parentPanel.style.cssText = 'display: flex !important; flex-direction: column !important; overflow: hidden !important; height: 100% !important;';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Применяем настройки wrap text после исправления всех контейнеров
|
||||||
|
applyWrapSettings();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Оставляем старую функцию для обратной совместимости
|
||||||
|
window.fixProblematicContainers = function() {
|
||||||
|
console.log('fixProblematicContainers is deprecated, use fixAllContainers instead');
|
||||||
|
window.fixAllContainers();
|
||||||
|
};
|
||||||
|
|
||||||
console.log('LogBoard+ инициализирован с исправлениями дублирования строк и правильными переносами строк в Single View и MultiView режимах');
|
console.log('LogBoard+ инициализирован с исправлениями дублирования строк и правильными переносами строк в Single View и MultiView режимах');
|
||||||
console.log('Для тестирования используйте: testDuplicateRemoval(), testSingleViewDuplicateRemoval(), testSingleViewEmptyLinesRemoval() или testSingleViewLineBreaks()');
|
console.log('Для тестирования используйте: testDuplicateRemoval(), testSingleViewDuplicateRemoval(), testSingleViewEmptyLinesRemoval() или testSingleViewLineBreaks()');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user