import * as React from 'react'; import type { WebPartContext } from '@microsoft/sp-webpart-base'; import { ApprovalQueueKind, filterPendingByQuery, getApprovalQueue, getApprovalQueueIndex, getLinkedTypes, getOwnRequests, getOwnRequestsByStatus, hydrateDecisionComments, hydratePendingAuthors, searchOwnRequests, } from './myRequests.service'; import { IMyRequest } from './models/IMyRequest'; import { DataTable, IDataTableColumn } from '@tnsu/ui-kit'; import { REQUEST_STATUS, REQUEST_STATUS_CHOICES, IRequestType, StatusBadge } from '../../shared/approval'; import { onRequestsChanged } from '../../shared/requestEvents'; import { perfScope } from '../../shared/perfTrace'; import { useRoutedQuery } from '../../shared/usePersistedQuery'; import { IPage, pageKey, pageSignature, readPage, writePage } from './pageCache'; import { Pager } from './Pager'; import styles from './RequestsTableView.module.scss'; const PAGE_SIZE = 20; // Автообновление открытых таблиц: раз в 10 минут перечитываем данные, чтобы // вкладка, оставленная открытой надолго, не показывала устаревший список. // Обновление фоновое — строки с экрана не пропадают и перерисовываются, только // если данные реально изменились (см. pageSignature). const AUTO_REFRESH_MS = 10 * 60 * 1000; /** * Что именно показывает таблица. Один компонент обслуживает все списки заявок * портала, а различаются они только источником строк и набором колонок: * * 'approvals' | 'execution' — очереди действий (из строк маршрута); * 'rework' — свои заявки, возвращённые на доработку; * 'own:created' — свои заявки (+ фильтр по статусу); * 'own:approved'|'own:rejected'|'own:executed' — история своих решений. */ export type ListView = | 'approvals' | 'execution' | 'rework' | 'own:created' | 'own:approved' | 'own:rejected' | 'own:executed'; // Представления, которые строятся на строках маршрута пользователя, и их очередь // в сервисе. Всё, чего здесь нет ('rework'/'own:created'), читается из списка // данных по автору. const QUEUE_BY_VIEW: { [key: string]: ApprovalQueueKind } = { approvals: 'approvals', execution: 'execution', 'own:approved': 'approved', 'own:rejected': 'rejected', 'own:executed': 'executed', }; const HEADINGS: Record = { approvals: 'Ждут вашего согласования', execution: 'Ждут вашего исполнения', rework: 'Возвращены вам на доработку', 'own:created': 'Инициированные мной', 'own:approved': 'Согласованные мной', 'own:rejected': 'Отклонённые мной', 'own:executed': 'Выполненные мной', }; const EMPTY_TEXTS: Record = { approvals: 'Нет заявок, ждущих вашего согласования.', execution: 'Нет заявок, ждущих вашего исполнения.', rework: 'Нет заявок, возвращённых вам на доработку.', 'own:created': 'Вы ещё не создавали заявок.', 'own:approved': 'Вы ещё ничего не согласовали.', 'own:rejected': 'Вы ещё ничего не отклоняли.', 'own:executed': 'Вы ещё ничего не выполнили.', }; // Цвет пункта в выпадающем списке фильтра — то же сопоставление статус→цвет, // что в StatusBadge (VARIANT), только цвет текста, а не бейдж целиком: внутри // нативного