AURORA-1683 комментарии: тип, запрос, время по Москве, счётчик строки панели
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
07648ba3ac
commit
ff2232787f
@ -1,5 +1,5 @@
|
||||
import { api } from '../../api/client';
|
||||
import type { DocumentOut, EntryOut, Page, StatementOut, StatementPatch } from '../../types/api';
|
||||
import type { CommentOut, DocumentOut, EntryOut, Page, StatementOut, StatementPatch } from '../../types/api';
|
||||
|
||||
const ENTRIES_PAGE = 2000;
|
||||
|
||||
@ -23,4 +23,7 @@ export async function getAllEntries(id: string): Promise<EntryOut[]> {
|
||||
}
|
||||
|
||||
/** Комментарий к документу: текст 1–4000 символов после обрезки пробелов (иначе 422). */
|
||||
export const postComment = (documentId: string, text: string) => api.post(`/documents/${documentId}/comments`, { text });
|
||||
export const postComment = (documentId: string, text: string) => api.post<CommentOut>(`/documents/${documentId}/comments`, { text });
|
||||
|
||||
/** Комментарии к документу по возрастанию времени, с ФИО автора. */
|
||||
export const getComments = (documentId: string) => api.get<CommentOut[]>(`/documents/${documentId}/comments`);
|
||||
|
||||
@ -75,6 +75,13 @@ export interface DocumentBrief {
|
||||
comments_count: number;
|
||||
issue_counts: IssueCountsOut;
|
||||
}
|
||||
/** Комментарий к документу (`GET /documents/{id}/comments`); правки и удаления нет. */
|
||||
export interface CommentOut {
|
||||
id: string;
|
||||
text: string;
|
||||
author: { id: string; full_name: string };
|
||||
created_at: string;
|
||||
}
|
||||
export type FileType = 'XLS' | 'XLSX' | 'XLSB' | 'PDF' | 'PNG' | 'JPG';
|
||||
export interface FileOut {
|
||||
id: string;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { formatMoscowDate, isIsoDate } from './dates';
|
||||
import { formatMoscowDate, formatMoscowDateTime, isIsoDate } from './dates';
|
||||
|
||||
describe('formatMoscowDate', () => {
|
||||
it('момент времени из API (UTC) — дата по Москве', () => {
|
||||
@ -12,6 +12,17 @@ describe('formatMoscowDate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatMoscowDateTime', () => {
|
||||
it('момент из API (UTC) — дата и время по Москве', () => {
|
||||
expect(formatMoscowDateTime('2026-10-07T23:11:42.981145Z')).toBe('08.10.2026 02:11');
|
||||
expect(formatMoscowDateTime('2024-03-12T10:05:00Z')).toBe('12.03.2024 13:05');
|
||||
});
|
||||
it('пусто и мусор', () => {
|
||||
expect(formatMoscowDateTime(null)).toBeNull();
|
||||
expect(formatMoscowDateTime('не дата')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isIsoDate', () => {
|
||||
it('строго ГГГГ-ММ-ДД и существующая дата', () => {
|
||||
expect(isIsoDate('2024-12-31')).toBe(true);
|
||||
|
||||
@ -7,6 +7,23 @@ export function formatMoscowDate(iso: string | null | undefined): string | null
|
||||
return Number.isNaN(date.getTime()) ? null : MOSCOW.format(date);
|
||||
}
|
||||
|
||||
const MOSCOW_DATE_TIME = new Intl.DateTimeFormat('ru-RU', {
|
||||
timeZone: 'Europe/Moscow',
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hourCycle: 'h23',
|
||||
});
|
||||
|
||||
/** Момент времени из API (ISO, UTC) → «dd.mm.yyyy hh:mm» по Москве; пусто/мусор → null. */
|
||||
export function formatMoscowDateTime(iso: string | null | undefined): string | null {
|
||||
if (!iso) return null;
|
||||
const date = new Date(iso);
|
||||
return Number.isNaN(date.getTime()) ? null : MOSCOW_DATE_TIME.format(date).replace(', ', ' ');
|
||||
}
|
||||
|
||||
/** Строго «ГГГГ-ММ-ДД» и существующая календарная дата (30 февраля — нет). */
|
||||
export function isIsoDate(text: string): boolean {
|
||||
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(text);
|
||||
|
||||
@ -169,6 +169,18 @@ describe('buildDocumentRows: предупреждения', () => {
|
||||
const rows = buildDocumentRows([file({ documents: [doc({ issue_counts: { error: 1, info: 3 } })] })]);
|
||||
expect(rows[0].issueCounts).toEqual({ error: 1, info: 3 });
|
||||
});
|
||||
|
||||
it('comments_count документа переносится в commentsCount', () => {
|
||||
const rows = buildDocumentRows([file({ documents: [doc({ comments_count: 2 })] })]);
|
||||
expect(rows[0].commentsCount).toBe(2);
|
||||
});
|
||||
|
||||
it('ядро без comments_count и строка файла без документов — 0', () => {
|
||||
const old = doc() as Partial<DocumentBrief>;
|
||||
old.comments_count = undefined;
|
||||
expect(buildDocumentRows([file({ documents: [old as DocumentBrief] })])[0].commentsCount).toBe(0);
|
||||
expect(buildDocumentRows([file({ status: 'PROCESSING' })])[0].commentsCount).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rowBadge', () => {
|
||||
|
||||
@ -27,6 +27,8 @@ export interface DocumentRow {
|
||||
mappingWarnings: string[];
|
||||
/** счётчики issues документа; у строки файла без документов — нули */
|
||||
issueCounts: IssueCountsOut;
|
||||
/** число комментариев документа; у строки файла без документов — 0 */
|
||||
commentsCount: number;
|
||||
}
|
||||
|
||||
/** Значок у статуса (P6-12): число предупреждений и цвет уровня; ничего нет — null. */
|
||||
@ -78,6 +80,7 @@ export function buildDocumentRows(files: FileOut[], labelFor?: (f: FileOut) => s
|
||||
fileWarnings,
|
||||
mappingWarnings,
|
||||
issueCounts: { error: 0, info: 0 },
|
||||
commentsCount: 0,
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -105,6 +108,7 @@ export function buildDocumentRows(files: FileOut[], labelFor?: (f: FileOut) => s
|
||||
mappingWarnings,
|
||||
// ядро без v5.19 не присылает issue_counts — считаем, что замечаний нет
|
||||
issueCounts: d.issue_counts ?? { error: 0, info: 0 },
|
||||
commentsCount: d.comments_count ?? 0,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user