refactor(frontend): обновление компонентов документов

- Удалены ссылки на document_type из DocumentUploadForm
- Удалены фильтры по статусам из DocumentRelated
- Удалены статистика статусов из DocumentsDashboard
- Обновлены экспорты компонентов (удалены устаревшие)
- Добавлены экспорты для новых компонентов тегов
This commit is contained in:
lizerk 2026-03-06 12:26:43 +03:00
parent 8c6753c188
commit bf493ba9d2
5 changed files with 67 additions and 55 deletions

View File

@ -8,7 +8,6 @@ import { toast } from "sonner";
interface RelatedDocument {
id: number;
title: string;
status: string;
created_at: string;
file_name?: string;
}
@ -105,32 +104,6 @@ export function DocumentRelated({ documentId, onNavigate }: DocumentRelatedProps
}
};
const getStatusBadge = (status: string) => {
const colors: Record<string, string> = {
draft: "bg-gray-100 text-gray-700",
in_review: "bg-yellow-100 text-yellow-700",
approved: "bg-green-100 text-green-700",
published: "bg-blue-100 text-blue-700",
archived: "bg-gray-100 text-gray-500",
rejected: "bg-red-100 text-red-700",
};
const labels: Record<string, string> = {
draft: "Черновик",
in_review: "На рассмотрении",
approved: "Утверждено",
published: "Опубликовано",
archived: "В архиве",
rejected: "Отклонено",
};
return (
<span className={`inline-block rounded-full px-2 py-0.5 text-xs ${colors[status] || colors.draft}`}>
{labels[status] || status}
</span>
);
};
if (loading) {
return (
<div className="flex items-center justify-center py-8">
@ -203,9 +176,6 @@ export function DocumentRelated({ documentId, onNavigate }: DocumentRelatedProps
{doc.title}
</span>
</div>
<div className="mt-1">
{getStatusBadge(doc.status)}
</div>
</div>
<button
onClick={() => handleAdd(doc.id)}
@ -255,7 +225,6 @@ export function DocumentRelated({ documentId, onNavigate }: DocumentRelatedProps
)}
</div>
<div className="mt-1 flex items-center gap-2">
{getStatusBadge(doc.status)}
<span className="text-xs text-gray-400">
{new Date(doc.created_at).toLocaleDateString("ru-RU")}
</span>

View File

@ -62,11 +62,17 @@ export function DocumentUploadForm({ onSuccess, onCancel, currentFolderId }: Doc
const [selectedDepartments, setSelectedDepartments] = useState<number[]>([]);
const [selectedRecipients, setSelectedRecipients] = useState<number[]>([]);
// Metadata fields
const [selectedTags, setSelectedTags] = useState<number[]>([]);
// Data for selects
const [departments, setDepartments] = useState<Department[]>([]);
const [employees, setEmployees] = useState<User[]>([]);
const [documentTags, setDocumentTags] = useState<any[]>([]);
const [loadingDepartments, setLoadingDepartments] = useState(false);
const [loadingEmployees, setLoadingEmployees] = useState(false);
const [loadingDocumentTags, setLoadingDocumentTags] = useState(false);
// Load departments and employees
useEffect(() => {
@ -90,6 +96,16 @@ export function DocumentUploadForm({ onSuccess, onCancel, currentFolderId }: Doc
} finally {
setLoadingEmployees(false);
}
try {
setLoadingDocumentTags(true);
const tagsResponse = await apiClient.getDocumentTags();
setDocumentTags(tagsResponse.results || tagsResponse);
} catch (err) {
console.error("Ошибка загрузки тегов:", err);
} finally {
setLoadingDocumentTags(false);
}
};
loadData();
@ -194,6 +210,7 @@ export function DocumentUploadForm({ onSuccess, onCancel, currentFolderId }: Doc
department_ids: sentToAll ? undefined : selectedDepartments,
recipient_ids: sentToAll ? undefined : selectedRecipients,
acknowledgement_required: acknowledgementRequired,
tag_ids: selectedTags.length > 0 ? selectedTags : undefined,
});
toast.success("Документ успешно загружен");
@ -208,6 +225,7 @@ export function DocumentUploadForm({ onSuccess, onCancel, currentFolderId }: Doc
setAcknowledgementRequired(false);
setSelectedDepartments([]);
setSelectedRecipients([]);
setSelectedTags([]);
if (onSuccess) {
onSuccess();
@ -350,6 +368,48 @@ export function DocumentUploadForm({ onSuccess, onCancel, currentFolderId }: Doc
/>
</div>
{/* Divider */}
<div className="border-t border-gray-200 pt-4">
<h3 className="mb-3 text-sm font-semibold text-gray-700 flex items-center gap-2">
<TagIcon size={16} />
Категоризация
</h3>
</div>
{/* Tags */}
<div>
<label htmlFor="tags" className="mb-1.5 block text-sm font-medium text-gray-700">
Теги
</label>
<select
id="tags"
multiple
value={selectedTags.map(String)}
onChange={(e) => {
const values = Array.from(e.target.selectedOptions, (option) => Number(option.value));
setSelectedTags(values);
}}
disabled={loadingDocumentTags}
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-100"
size={4}
>
{loadingDocumentTags ? (
<option disabled>Загрузка...</option>
) : documentTags.length === 0 ? (
<option disabled>Нет доступных тегов</option>
) : (
documentTags.map((tag) => (
<option key={tag.id} value={tag.id}>
{tag.name}
</option>
))
)}
</select>
<p className="mt-1 text-xs text-gray-500">
Удерживайте Ctrl/Cmd для выбора нескольких тегов
</p>
</div>
{/* Извлеченный текст */}
{extractedText && (
<div>

View File

@ -59,7 +59,6 @@ interface DocumentsDashboardProps {
myDocuments?: Array<{
id: number;
title: string;
status?: string;
uploaded_at: string;
}>;
}
@ -153,24 +152,6 @@ export function DocumentsDashboard({
</div>
</div>
{/* Одобренные */}
<div className="rounded-lg border border-gray-200 bg-white p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-600">Одобренные</p>
<p className="mt-1 text-2xl font-bold text-gray-900">
{
stats.documentsByStatus.find((s) => s.status === "approved" || s.status === "Одобрено")
?.count || 0
}
</p>
</div>
<div className="rounded-full bg-emerald-100 p-3">
<CheckCircle2 size={24} className="text-emerald-600" />
</div>
</div>
</div>
{/* Активность */}
<div className="rounded-lg border border-gray-200 bg-white p-4">
<div className="flex items-center justify-between">
@ -356,9 +337,6 @@ export function DocumentsDashboard({
>
<p className="truncate text-sm font-medium text-gray-900">{doc.title}</p>
<p className="text-xs text-gray-500">
{doc.status && (
<span className="mr-2 rounded bg-gray-100 px-1">{doc.status}</span>
)}
{new Date(doc.uploaded_at).toLocaleDateString("ru-RU")}
</p>
</div>

View File

@ -1,14 +1,14 @@
export { DocumentUploadForm } from "./DocumentUploadForm";
export { DocumentStatusBadge } from "./DocumentStatusBadge";
export { DocumentWorkflowButtons } from "./DocumentWorkflowButtons";
export { DocumentPreview } from "./DocumentPreview";
export { DocumentAcknowledgement } from "./DocumentAcknowledgement";
export { DocumentAcknowledgementsReport } from "./DocumentAcknowledgementsReport";
export { DocumentDetailModal } from "./DocumentDetailModal";
export { DocumentMetadataEditor } from "./DocumentMetadataEditor";
// New features
export { default as DocumentThumbnail } from "./DocumentThumbnail";
export * from "./comments";
export * from "./tags";
export * from "./types";
export * from "./versions";
export * from "./related";

View File

@ -1,3 +1,8 @@
export { default as TagBadge } from './TagBadge';
export { default as TagSelect } from './TagSelect';
export { default as TagManager } from './TagManager';
// Tag Management Components
export { TagManagementModal } from './TagManagementModal';
export { TagForm } from './TagForm';
export { TagColorPicker } from './TagColorPicker';