diff --git a/web/src/components/common/DeletionMarkChip.jsx b/web/src/components/common/DeletionMarkChip.jsx
new file mode 100644
index 0000000..289640e
--- /dev/null
+++ b/web/src/components/common/DeletionMarkChip.jsx
@@ -0,0 +1,11 @@
+import { Tooltip } from '@mui/material';
+import { formatDeletionHint } from '../../utils/formatDeletionHint';
+import { Chip } from '../styles/StyledChip';
+
+const chipSx = { background: '#fde8e8', color: '#b42318', whiteSpace: 'nowrap', width: 'max-content', cursor: 'default' };
+
+export const DeletionMarkChip = ({ task, usersById, sx = {} }) => (
+
+ На удаление
+
+);
diff --git a/web/src/components/common/TaskCardComponent.jsx b/web/src/components/common/TaskCardComponent.jsx
index 07cde07..128f9c1 100644
--- a/web/src/components/common/TaskCardComponent.jsx
+++ b/web/src/components/common/TaskCardComponent.jsx
@@ -9,6 +9,7 @@ import { TasksApi } from '../../api/tasks';
import { FORM_TYPE_TRANSLATE } from '../../constants/constants';
import { ExportButton } from '../common/Buttons/ButtonsActions';
import { Chip } from '../styles/StyledChip';
+import { DeletionMarkChip } from './DeletionMarkChip';
import { LastOpenedBadge } from './LastOpenedBadge';
import { IconWithContent } from './IconWithContent';
import Modal from './Modal/Modal';
@@ -62,6 +63,7 @@ export const TaskCardComponent = ({
isAdmin = false,
onChanged,
currentUserId = null,
+ usersById = {},
}) => {
const navigate = useNavigate();
const location = useLocation();
@@ -213,7 +215,7 @@ export const TaskCardComponent = ({
ID: {id}
- {taskForm.to_delete && На удаление}
+ {taskForm.to_delete && }
{isLastOpened && Последняя открытая}
diff --git a/web/src/pages/TaskPage/TaskPage.jsx b/web/src/pages/TaskPage/TaskPage.jsx
index 91d37e3..fd77b74 100644
--- a/web/src/pages/TaskPage/TaskPage.jsx
+++ b/web/src/pages/TaskPage/TaskPage.jsx
@@ -4,9 +4,11 @@ import { useNavigate, useParams } from 'react-router-dom';
import { toast } from 'react-toastify';
import { ProjectsApi } from '../../api/projects'; // Добавьте импорт API для проектов
import { TasksApi } from '../../api/tasks';
+import { UsersApi } from '../../api/users';
import { SettingModal as SettingStageModal } from '../../components/Stages/SettingModal';
import { DangerOutlinedButton, PrimaryButton, PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons';
import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
+import { DeletionMarkChip } from '../../components/common/DeletionMarkChip';
import { IconWithContent } from '../../components/common/IconWithContent';
import { HeaderPortal } from '../../components/common/HeaderPortal';
import SearchComponent from '../../components/common/SearchComponent';
@@ -49,6 +51,15 @@ export default function TaskPage() {
const [addYearModalOpen, setAddYearModalOpen] = useState(false);
const [isAddingYear, setIsAddingYear] = useState(false);
const [dataReloadKey, setDataReloadKey] = useState(0);
+ const [usersById, setUsersById] = useState({});
+ const isMarkedForDeletion = Boolean(task?.to_delete);
+
+ useEffect(() => {
+ if (!isMarkedForDeletion) return;
+ UsersApi.getAll()
+ .then((data) => setUsersById(Object.fromEntries((data.result || []).map((item) => [item.id, item]))))
+ .catch(() => toast.error('Ошибка загрузки пользователей'));
+ }, [isMarkedForDeletion]);
useEffect(() => {
const getData = async () => {
@@ -162,6 +173,7 @@ export default function TaskPage() {
Таблиц: {tables.length}
+ {isMarkedForDeletion && }
diff --git a/web/src/pages/TasksPage/TasksTable.jsx b/web/src/pages/TasksPage/TasksTable.jsx
index 52ea827..fe97cc7 100644
--- a/web/src/pages/TasksPage/TasksTable.jsx
+++ b/web/src/pages/TasksPage/TasksTable.jsx
@@ -5,6 +5,7 @@ import { Link as RouterLink, useLocation, useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify';
import { TasksApi } from '../../api/tasks';
import { ExportButton, ExportExitButton, ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
+import { DeletionMarkChip } from '../../components/common/DeletionMarkChip';
import FormBadge from '../../components/common/FormBadge';
import { LastOpenedBadge } from '../../components/common/LastOpenedBadge';
import Modal from '../../components/common/Modal/Modal';
@@ -84,6 +85,7 @@ export default function TasksTable({
sx={{ color: 'inherit', fontWeight: 500, fontSize: '1rem' }}>
{cell.getValue()}
+ {row.original.to_delete && }
{String(row.original.id) === lastOpenedId && (
Последняя открытая
@@ -106,7 +108,7 @@ export default function TasksTable({
{creator?.is_active === false && (
- Отправлен на удаление
+ Пользователь удалён
)}
diff --git a/web/src/utils/formatDeletionHint.test.js b/web/src/utils/formatDeletionHint.test.js
index ad33e98..e77ab62 100644
--- a/web/src/utils/formatDeletionHint.test.js
+++ b/web/src/utils/formatDeletionHint.test.js
@@ -6,10 +6,7 @@ const at = new Date(2026, 10, 5, 9, 7).toISOString();
const users = { 7: { id: 7, full_name: ' Иванов Иван ', username: 'ivanov' } };
test('дата и ФИО', () => {
- assert.equal(
- formatDeletionHint({ deleted_at: at, deleted_by: 7 }, users),
- 'Отправлена на удаление 05.11.2026 09:07 — Иванов Иван',
- );
+ assert.equal(formatDeletionHint({ deleted_at: at, deleted_by: 7 }, users), 'Отправлена на удаление 05.11.2026 09:07 — Иванов Иван');
});
test('без deleted_by', () => {
@@ -31,5 +28,8 @@ test('deleted_by нет в справочнике', () => {
});
test('нет full_name — username; невалидная дата игнорируется', () => {
- assert.equal(formatDeletionHint({ deleted_at: 'мусор', deleted_by: 8 }, { 8: { username: 'petrov' } }), 'Отправлена на удаление — petrov');
+ assert.equal(
+ formatDeletionHint({ deleted_at: 'мусор', deleted_by: 8 }, { 8: { username: 'petrov' } }),
+ 'Отправлена на удаление — petrov',
+ );
});