diff --git a/README.md b/README.md
index bf9065c..eb1cf2e 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@ LogBoard+ особенно полезен для разработчиков, р
### Основные возможности
- **Просмотр логов в реальном времени** - WebSocket соединения для live-логов
+- **Multi-view режим** - Одновременный просмотр логов нескольких контейнеров
+- **Drag & Drop** - Перетаскивание окон для изменения порядка в multi-view режиме
- **Поддержка множественных проектов** - Фильтрация по проектам Docker Compose
- **Безопасность** - JWT аутентификация и авторизация
- **Фильтрация контейнеров** - Исключение проблемных контейнеров
@@ -395,6 +397,18 @@ curl http://localhost:9001/healthz
- Количество исключенных контейнеров
- Время ответа API
+## Документация
+
+Подробная документация по всем аспектам LogBoard+:
+
+- **[Установка и настройка](docs/installation.md)** - Пошаговое руководство по установке
+- **[Конфигурация](docs/configuration.md)** - Настройка переменных окружения и параметров
+- **[API документация](docs/api.md)** - REST API и WebSocket API
+- **[Управление проектом](docs/management.md)** - Makefile и Docker Compose команды
+- **[Безопасность](docs/security.md)** - Рекомендации по безопасности
+- **[Устранение неполадок](docs/troubleshooting.md)** - Решение проблем
+- **[Drag & Drop](docs/drag-and-drop.md)** - Перетаскивание окон в multi-view режиме
+
## Разработка
### Локальная разработка
@@ -493,6 +507,13 @@ MIT License - см. файл [LICENSE](LICENSE) для подробностей.
## Changelog
+### v2.0.0 (2024-01-XX)
+- **Drag & Drop для multi-view** - Перетаскивание окон для изменения порядка
+- Улучшенный интерфейс multi-view режима
+- Визуальные индикаторы перетаскивания
+- Автоматическое сохранение порядка окон
+- Обновленная документация
+
### v1.0.0 (2024-01-XX)
- Первый релиз LogBoard+
- Поддержка множественных проектов Docker Compose
diff --git a/app/start.sh b/app/start.sh
new file mode 100755
index 0000000..e69de29
diff --git a/app/static/css/index.css b/app/static/css/index.css
index dabb3f9..9ed0de6 100644
--- a/app/static/css/index.css
+++ b/app/static/css/index.css
@@ -2582,3 +2582,126 @@ footer{position:fixed;right:10px;bottom:10px;opacity:.6;font-size:11px}
.notification-close:hover {
background: var(--chip);
color: var(--fg);
+}
+
+/* Мультипросмотр */
+.multi-view-grid {
+ display: grid;
+ gap: 2px;
+ height: 100%;
+ padding: 0px;
+ /* Равная высота строк для нескольких рядов (3+ окон) */
+ grid-auto-rows: 1fr;
+ align-items: stretch;
+}
+
+/* Drag & Drop стили для multi-view */
+.multi-view-panel {
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ padding: 2px;
+ cursor: move; /* Курсор для перетаскивания */
+ user-select: none; /* Запрещаем выделение текста при перетаскивании */
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+ position: relative;
+}
+
+/* Стили для перетаскиваемого элемента */
+.multi-view-panel.dragging {
+ opacity: 0.8;
+ transform: scale(1.02);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ cursor: grabbing;
+}
+
+/* Стили для области, куда можно бросить элемент */
+.multi-view-panel.drag-over {
+ border-color: var(--accent);
+ background: var(--tab-active);
+ transform: scale(1.01);
+}
+
+/* Индикатор перетаскивания в заголовке */
+.multi-view-header {
+ padding: 5px 16px;
+ background: var(--chip);
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ min-height: 16px;
+ cursor: grab; /* Курсор для перетаскивания в заголовке */
+}
+
+.multi-view-header:active {
+ cursor: grabbing;
+}
+
+/* Иконка перетаскивания */
+.drag-handle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 16px;
+ height: 16px;
+ color: var(--muted);
+ cursor: grab;
+ margin-right: 8px;
+ transition: color 0.2s ease;
+}
+
+.drag-handle:hover {
+ color: var(--accent);
+}
+
+.drag-handle:active {
+ cursor: grabbing;
+}
+
+/* Подсказка для перетаскивания */
+.drag-tooltip {
+ position: absolute;
+ top: -30px;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 4px 8px;
+ font-size: 11px;
+ color: var(--fg);
+ white-space: nowrap;
+ z-index: 1001;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.2s ease, visibility 0.2s ease;
+}
+
+.drag-tooltip.show {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* Анимация для перестановки элементов */
+.multi-view-panel {
+ transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
+}
+
+/* Стили для сетки при перетаскивании */
+.multi-view-grid.dragging {
+ gap: 4px; /* Увеличиваем отступы для лучшей видимости */
+}
+
+/* Стили для placeholder при перетаскивании */
+.multi-view-panel.drag-placeholder {
+ background: var(--chip);
+ border: 2px dashed var(--accent);
+ opacity: 0.5;
+ pointer-events: none;
+}
diff --git a/app/static/js/index.js b/app/static/js/index.js
index cae90dd..9401ca8 100644
--- a/app/static/js/index.js
+++ b/app/static/js/index.js
@@ -1838,6 +1838,9 @@ async function setupMultiView() {
// Обновляем видимость кнопок LogLevels
updateLogLevelsVisibility();
+
+ // Обновляем drag & drop для новых панелей
+ updateDragAndDrop();
}
/**
@@ -1854,7 +1857,10 @@ function createMultiViewPanel(service) {
console.log(`createMultiViewPanel: Panel element created with data-container-id: ${service.id}`);
panel.innerHTML = `
-
+
+
+
Multi-View
+
+ - Перетащите заголовок окна Изменить порядок окон
+ - Иконка ⋮⋮ в заголовке Индикатор перетаскивания
+
+
diff --git a/docker-compose.yml b/docker-compose.yml
index 3222731..b5c0ffe 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,6 +9,8 @@ services:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./snapshots:/app/snapshots
+ - ./app:/app
+ - ./start.sh:/app/start.sh
restart: unless-stopped
user: 0:0
networks:
diff --git a/docs/drag-and-drop.md b/docs/drag-and-drop.md
new file mode 100644
index 0000000..5237d0d
--- /dev/null
+++ b/docs/drag-and-drop.md
@@ -0,0 +1,182 @@
+# Drag & Drop для Multi-View режима
+
+## Обзор
+
+LogBoard+ поддерживает drag & drop функциональность в режиме мультипросмотра (multi-view), позволяя пользователям изменять порядок окон логов путем перетаскивания их заголовков.
+
+## Возможности
+
+### Основные функции
+- **Перетаскивание окон**: Изменение порядка окон логов в multi-view режиме
+- **Визуальная обратная связь**: Анимации и стили во время перетаскивания
+- **Сохранение порядка**: Автоматическое сохранение нового порядка в localStorage
+- **Placeholder**: Визуальный индикатор места вставки во время перетаскивания
+
+### Индикаторы перетаскивания
+- **Иконка ⋮⋮**: Отображается в заголовке каждого окна
+- **Курсор**: Изменяется на `grab`/`grabbing` при наведении и перетаскивании
+- **Подсказки**: Всплывающие подсказки с инструкциями
+
+## Использование
+
+### Как перетащить окно
+1. **Включите multi-view режим**: Выберите несколько контейнеров (Shift+клик или Ctrl+клик)
+2. **Найдите иконку перетаскивания**: В заголовке каждого окна есть иконка ⋮⋮
+3. **Начните перетаскивание**: Нажмите и удерживайте левую кнопку мыши на заголовке окна
+4. **Переместите окно**: Перетащите окно в нужную позицию
+5. **Отпустите кнопку мыши**: Окно встанет на новое место
+
+### Визуальные эффекты
+- **Во время перетаскивания**:
+ - Окно становится полупрозрачным
+ - Появляется тень
+ - Окно слегка увеличивается
+ - Создается placeholder на месте исходного окна
+
+- **При наведении на другие окна**:
+ - Окна подсвечиваются синим цветом
+ - Показывается, куда будет вставлено окно
+
+## Техническая реализация
+
+### CSS классы
+```css
+.multi-view-panel.dragging {
+ opacity: 0.8;
+ transform: scale(1.02);
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ cursor: grabbing;
+}
+
+.multi-view-panel.drag-over {
+ border-color: var(--accent);
+ background: var(--tab-active);
+ transform: scale(1.01);
+}
+
+.multi-view-panel.drag-placeholder {
+ background: var(--chip);
+ border: 2px dashed var(--accent);
+ opacity: 0.5;
+ pointer-events: none;
+}
+```
+
+### JavaScript функции
+- `initDragAndDrop()`: Инициализация drag & drop
+- `handleDragStart()`: Обработчик начала перетаскивания
+- `handleDragEnd()`: Обработчик окончания перетаскивания
+- `handleDrop()`: Обработчик сброса элемента
+- `reorderMultiViewPanels()`: Перестановка панелей
+- `updateDragAndDrop()`: Обновление drag & drop для новых панелей
+
+### Состояние перетаскивания
+```javascript
+let dragState = {
+ isDragging: false,
+ draggedElement: null,
+ draggedIndex: -1,
+ originalIndex: -1,
+ placeholder: null
+};
+```
+
+## Ограничения
+
+### Поддерживаемые браузеры
+- Chrome 66+
+- Firefox 60+
+- Safari 12+
+- Edge 79+
+
+### Условия работы
+- Только в multi-view режиме (2+ контейнера)
+- Только перетаскивание заголовков окон
+- Не работает в single-view режиме
+
+## Настройки
+
+### Сохранение порядка
+Порядок окон автоматически сохраняется в localStorage и восстанавливается при перезагрузке страницы.
+
+### Отключение функциональности
+Для отключения drag & drop можно удалить обработчики событий:
+```javascript
+document.removeEventListener('dragstart', handleDragStart);
+document.removeEventListener('dragend', handleDragEnd);
+// ... и другие обработчики
+```
+
+## Устранение неполадок
+
+### Проблемы с перетаскиванием
+1. **Окно не перетаскивается**:
+ - Убедитесь, что вы в multi-view режиме
+ - Проверьте, что перетаскиваете за заголовок окна
+ - Убедитесь, что браузер поддерживает HTML5 Drag & Drop
+
+2. **Порядок не сохраняется**:
+ - Проверьте, что localStorage доступен
+ - Убедитесь, что нет ошибок в консоли браузера
+
+3. **Визуальные эффекты не работают**:
+ - Проверьте, что CSS стили загружены
+ - Убедитесь, что нет конфликтов с другими стилями
+
+### Отладка
+Включите отладочные сообщения в консоли браузера:
+```javascript
+console.log('Drag & Drop Debug:', dragState);
+```
+
+## Примеры использования
+
+### Базовое перетаскивание
+```javascript
+// Автоматически инициализируется при загрузке страницы
+initDragAndDrop();
+```
+
+### Программное изменение порядка
+```javascript
+// Перестановка панелей программно
+reorderMultiViewPanels(0, 2); // Переместить первую панель на третье место
+```
+
+### Получение текущего порядка
+```javascript
+// Получить текущий порядок контейнеров
+const currentOrder = state.selectedContainers;
+console.log('Текущий порядок:', currentOrder);
+```
+
+## Совместимость
+
+### С существующим функционалом
+- Совместимо с AJAX обновлением логов
+- Работает с фильтрацией по уровням логирования
+- Поддерживает автопрокрутку и перенос строк
+- Интегрируется с системой сохранения настроек
+
+### Производительность
+- Минимальное влияние на производительность
+- Оптимизированные обработчики событий
+- Эффективное обновление DOM
+
+## Планы развития
+
+### Будущие улучшения
+- Поддержка перетаскивания между разными сетками
+- Анимации при изменении размера окон
+- Группировка окон по категориям
+- Экспорт/импорт конфигурации порядка окон
+
+### Обратная связь
+Для предложений по улучшению drag & drop функциональности обращайтесь к автору проекта.
+
+---
+
+**Автор**: Сергей Антропов
+**Сайт**: https://devops.org.ru
+**Версия**: 2.0