- utils/cellEditability.js: isCellEditable/isComputedColumn — чистые функции, isComputedColumn повторяет часть v3._apply_form_cell/_apply_form3_cell (0023_apply_cell_empty_string.sql), чтобы админ не видел вычисляемые колонки как редактируемые. tableColumns.jsx использует isCellEditable вместо инлайновой проверки. - useRealtimeData.js: возвращает stageColumnDeadlines (closes_at по колонке текущего этапа) рядом с columnsCurStage. - Cell.jsx: редактируемая ячейка — белый фон, рамка 1px #7FA7C9 (2px при наведении), курсор text; нередактируемая ячейка строки INPUT — фон #F4F5F7, текст #5F6B7A; занятая коллегой — пунктирная оранжевая рамка 2px #F0A030 без изменения фона. Строки ITEM/GROUP/ROOT не затронуты. Сохранён порядок стилей из AURORA-1894 (INVALID_STYLES последним) и спред fontWeight для отрицательных чисел из AURORA-1892. - TableHead.jsx: метка срока ввода «✎ до DD.MM HH:mm» в заголовке колонки текущего этапа, только для исполнителя (utils/deadlineFormat.js). - SettingPanel/CellLegend.jsx: иконка "?" с легендой (можно вводить / расчёт или закрыто) рядом с плашкой контроля ошибок, без новой панели и без новых цветов в palettes columnColors.js. node --test: cellEditability.test.js, deadlineFormat.test.js — 18/18. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
26 lines
1.0 KiB
JavaScript
26 lines
1.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { formatDeadline } from './deadlineFormat.js';
|
|
|
|
test('ISO closes_at is formatted as "до DD.MM HH:mm" in local time', () => {
|
|
const closesAt = new Date(2026, 9, 31, 18, 0, 0); // 31 октября, 18:00, локальное время
|
|
assert.equal(formatDeadline(closesAt.toISOString()), 'до 31.10 18:00');
|
|
});
|
|
|
|
test('single-digit day/month/hour/minute are zero-padded', () => {
|
|
const closesAt = new Date(2026, 0, 5, 9, 3, 0); // 5 января, 09:03
|
|
assert.equal(formatDeadline(closesAt.toISOString()), 'до 05.01 09:03');
|
|
});
|
|
|
|
test('a Date instance is accepted directly, not only an ISO string', () => {
|
|
const closesAt = new Date(2026, 11, 1, 0, 0, 0);
|
|
assert.equal(formatDeadline(closesAt), 'до 01.12 00:00');
|
|
});
|
|
|
|
test('falsy or invalid input returns null instead of throwing', () => {
|
|
assert.equal(formatDeadline(null), null);
|
|
assert.equal(formatDeadline(undefined), null);
|
|
assert.equal(formatDeadline(''), null);
|
|
assert.equal(formatDeadline('not-a-date'), null);
|
|
});
|