diff --git a/docs/guides/MODERN_DOCUMENT_UI.md b/docs/guides/MODERN_DOCUMENT_UI.md new file mode 100644 index 00000000..a4fa4bd5 --- /dev/null +++ b/docs/guides/MODERN_DOCUMENT_UI.md @@ -0,0 +1,262 @@ +# Современный UI для системы документооборота + +## Анализ рынка + +Проанализированы лучшие практики UI/UX из ведущих систем документооборота и управления проектами: + +### 1. Google Drive +- ✅ Превью документа в центре экрана +- ✅ Боковая панель с метаданными +- ✅ Вкладка "Активность" с временной шкалой +- ✅ Быстрые действия в header +- ✅ Breadcrumbs навигация + +### 2. Notion +- ✅ Чистый минималистичный дизайн +- ✅ Встроенный превью документов +- ✅ Комментарии и обсуждения +- ✅ Связанные документы +- ✅ История версий + +### 3. Confluence +- ✅ Табы для организации контента +- ✅ Timeline активности +- ✅ Версионирование с diff +- ✅ Метаданные в sidebar +- ✅ Workflow статусы + +### 4. SharePoint +- ✅ Расширенные метаданные +- ✅ Типы документов +- ✅ Workflow с согласованиями +- ✅ История изменений +- ✅ Права доступа + +### 5. ClickUp / Monday.com +- ✅ Статусы и workflow +- ✅ Назначение и получатели +- ✅ Комментарии и обсуждения +- ✅ Timeline с прогрессом +- ✅ Связи между документами + +## Новая архитектура UI + +### Компонент: DocumentDetailModal + +#### Структура + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Header (фиксированный) │ +│ - Заголовок документа + метаинфо (тип, размер, дата) │ +│ - Быстрые действия (Открыть, Скачать, Поделиться) │ +│ - Status badge │ +├─────────────────────────────────────────────────────────────┤ +│ Tabs Navigation (фиксированный) │ +│ [Обзор] [Активность] [Ознакомления] [Версии] │ +├─────────────────────────────────────────────────────────────┤ +│ Tab Content (прокручиваемый) │ +│ │ +│ Вкладка "Обзор": 2-колоночный layout │ +│ ┌──────────────────────┬─────────────────────┐ │ +│ │ Main Content (66%) │ Sidebar (33%) │ │ +│ │ • Превью документа │ • Информация │ │ +│ │ • Описание │ - Автор │ │ +│ │ • Действия workflow │ - Даты │ │ +│ │ │ • Расположение │ │ +│ │ │ • Теги │ │ +│ │ │ • Получатели │ │ +│ └──────────────────────┴─────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Вкладки + +#### 1. **Обзор** (overview) +- **Превью документа** - центральное место, крупный размер +- **Описание** - полное текстовое описание +- **Workflow Actions** - кнопки для изменения статуса +- **Sidebar с метаданными**: + - 📊 Информация (автор, даты создания/изменения) + - 📁 Расположение (breadcrumbs по папкам) + - 🏷 Теги (цветные badge'ы) + - 👥 Получатели (отделы и конкретные люди) + +#### 2. **Активность** (activity) +- Timeline с историей изменений +- События workflow (создан → на рассмотрении → одобрен → опубликован) +- Изменения метаданных +- **Интеграция с django-reversion** (требует API endpoint) + +#### 3. **Ознакомления** (acknowledgements) +- Прогресс: X/Y пользователей (Z%) +- Список кто прочитал с датой/временем +- Список кто ещё не прочитал +- Группировка по отделам +- Использует существующий `DocumentAcknowledgement` компонент + +#### 4. **Версии** (versions) +- История версий документа +- Diff между версиями +- Возможность восстановления предыдущей версии +- **Интеграция с django-reversion** (требует API endpoint) + +## Ключевые улучшения UX + +### 1. Прогрессивное раскрытие (Progressive Disclosure) +- Основная информация на вкладке "Обзор" +- Дополнительная информация на отдельных вкладках +- Не перегружаем пользователя сразу + +### 2. Визуальная иерархия +- Превью документа - самый заметный элемент +- Статус и действия - в header, всегда видны +- Метаданные в компактном sidebar + +### 3. Быстрые действия +- Header с кнопками: Открыть, Скачать, Поделиться +- Workflow actions в основной области +- Все важное доступно в 1 клик + +### 4. Информативность +- Больше контекста (тип документа, размер, даты) +- Breadcrumbs для понимания местоположения +- Теги для классификации +- Видимость получателей и прогресса ознакомления + +### 5. Масштабируемость +- Модальное окно на весь экран (size="full") +- Табы позволяют добавлять новые секции +- Структура готова к расширению (комментарии, связанные документы) + +## Интеграция с бэкендом + +### Уже реализовано ✅ +- DocumentReadSerializer с полными метаданными +- FSM workflow transitions (draft → review → approved → published → archived) +- DocumentAcknowledgement для отслеживания ознакомлений +- django-filer для управления файлами +- Типы документов и теги + +### Требует реализации ⚠️ + +#### 1. API для истории версий (django-reversion) +```python +# backend/api/v1/documents/views.py +@action(detail=True, methods=['get']) +def versions(self, request, pk=None): + """Получить историю версий документа""" + document = self.get_object() + versions = Version.objects.get_for_object(document) + # Сериализация versions + return Response(...) +``` + +#### 2. API для timeline активности +```python +@action(detail=True, methods=['get']) +def activity(self, request, pk=None): + """Получить временную шкалу активности""" + document = self.get_object() + # Собрать события: + # - Изменения workflow status + # - Изменения metadata + # - Ознакомления пользователей + # - История версий + return Response(...) +``` + +#### 3. API для комментариев (будущая фича) +```python +# Модель DocumentComment +class DocumentComment(models.Model): + document = ForeignKey(Document) + author = ForeignKey(User) + text = TextField() + created_at = DateTimeField(auto_now_add=True) + parent = ForeignKey('self', null=True) # для replies +``` + +## Использование компонента + +```tsx +import { DocumentDetailModal } from "@/components/documents"; + +function DocumentsPage() { + const [selectedDoc, setSelectedDoc] = useState(null); + + return ( + <> + {/* ... карточки документов ... */} + + setSelectedDoc(null)} + onUpdate={() => { + // Обновить список документов + loadDocuments(); + }} + onPreview={(url, name) => { + // Открыть превью в полном размере + setPreviewFile({ url, name }); + }} + /> + + ); +} +``` + +## Преимущества нового решения + +### Для пользователей +1. **Быстрый доступ к документу** - превью сразу в модалке +2. **Понятный workflow** - видно текущий статус и доступные действия +3. **Контроль ознакомлений** - прогресс и детали +4. **История изменений** - прозрачность процессов (после реализации API) +5. **Компактность** - вся информация организована в табы + +### Для разработки +1. **Модульность** - легко добавить новые вкладки +2. **Переиспользуемость** - один компонент вместо нескольких +3. **Масштабируемость** - готово к будущим фичам +4. **Типобезопасность** - TypeScript интерфейсы +5. **Согласованность** - единый стиль с Modal компонентом + +### Для бизнеса +1. **Профессиональный вид** - соответствует рыночным стандартам +2. **Производительность** - быстрый доступ к информации +3. **Прозрачность** - видна вся история и прогресс +4. **Гибкость** - легко кастомизировать под нужды +5. **Конкурентоспособность** - на уровне Confluence/SharePoint + +## Дорожная карта + +### Фаза 1: Базовый функционал ✅ +- [x] Создан компонент DocumentDetailModal +- [x] Вкладка "Обзор" с превью и метаданными +- [x] Вкладка "Ознакомления" с прогрессом +- [x] Интеграция с существующими компонентами + +### Фаза 2: История и версии ⏳ +- [ ] API endpoint для получения версий (django-reversion) +- [ ] Вкладка "Версии" с diff +- [ ] API endpoint для timeline активности +- [ ] Вкладка "Активность" с реальными данными + +### Фаза 3: Комментарии и обсуждения 📋 +- [ ] Модель DocumentComment +- [ ] API для комментариев (CRUD) +- [ ] Вкладка "Комментарии" +- [ ] Real-time уведомления о новых комментариях + +### Фаза 4: Расширенные возможности 🚀 +- [ ] Связанные документы +- [ ] @mentions в комментариях +- [ ] Прикрепление файлов к комментариям +- [ ] Экспорт истории и отчетов +- [ ] Поиск по комментариям + +## Заключение + +Новое модальное окно DocumentDetailModal приближает систему EUSRR к уровню профессиональных решений класса enterprise (SharePoint, Confluence). Структура с табами обеспечивает прогрессивное раскрытие информации, а интеграция с django-reversion и FSM workflow создает полноценную систему управления документами с прозрачностью всех процессов. diff --git a/frontend/src/components/documents/DocumentDetailModal.tsx b/frontend/src/components/documents/DocumentDetailModal.tsx new file mode 100644 index 00000000..c998edc7 --- /dev/null +++ b/frontend/src/components/documents/DocumentDetailModal.tsx @@ -0,0 +1,480 @@ +"use client"; + +import { useState } from "react"; +import { Modal } from "@/components/ui/Modal"; +import type { Document } from "@/types/api"; +import { + FileText, + User, + Calendar, + HardDrive, + FolderOpen, + Users, + Building2, + Tag, + Clock, + CheckCircle, + Eye, + Download, + Share2, + MoreVertical, + ChevronRight, + Activity, + History, + MessageSquare, +} from "lucide-react"; +import { DocumentStatusBadge } from "./DocumentStatusBadge"; +import { DocumentWorkflowButtons } from "./DocumentWorkflowButtons"; +import { DocumentAcknowledgement } from "./DocumentAcknowledgement"; + +interface DocumentDetailModalProps { + document: Document | null; + isOpen: boolean; + onClose: () => void; + onUpdate?: () => void; + onPreview?: (url: string, name: string) => void; +} + +type TabType = "overview" | "activity" | "acknowledgements" | "versions"; + +export function DocumentDetailModal({ + document, + isOpen, + onClose, + onUpdate, + onPreview, +}: DocumentDetailModalProps) { + const [activeTab, setActiveTab] = useState("overview"); + + if (!document) return null; + + const formatDate = (date: string) => { + return new Date(date).toLocaleDateString("ru-RU", { + day: "numeric", + month: "long", + year: "numeric", + hour: "2-digit", + minute: "2-digit", + }); + }; + + const formatFileSize = (bytes: number) => { + if (bytes < 1024) return `${bytes} Б`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} КБ`; + return `${(bytes / 1024 / 1024).toFixed(2)} МБ`; + }; + + const tabs = [ + { id: "overview" as TabType, label: "Обзор", icon: FileText }, + { id: "activity" as TabType, label: "Активность", icon: Activity }, + { id: "acknowledgements" as TabType, label: "Ознакомления", icon: CheckCircle }, + { id: "versions" as TabType, label: "Версии", icon: History }, + ]; + + return ( + + {(isFullscreen) => ( +
+ {/* Header with Title and Actions */} +
+
+
+

{document.title}

+
+ {document.document_type && ( + + + {document.document_type.name} + + )} + {document.file_name && ( + + + {document.file_size && formatFileSize(document.file_size)} + + )} + + + {formatDate(document.uploaded_at || document.created_at)} + +
+
+ + {/* Quick Actions */} +
+ + {document.file_url && ( + <> + + + + + + )} + + +
+
+
+ + {/* Tabs Navigation */} +
+ +
+ + {/* Tab Content */} +
+ {activeTab === "overview" && ( +
+ {/* Main Content - Preview & Description */} +
+ {/* Document Preview */} + {document.file_url && ( +
+
+ {(() => { + const fileExt = document.file_name?.toLowerCase().split(".").pop() || ""; + const isImage = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"].includes(fileExt); + const isPDF = fileExt === "pdf"; + + if (isImage) { + return ( + {document.file_name + ); + } + + if (isPDF) { + return ( +