import * as React from 'react'; // Текст поиска переживает перезагрузку страницы (localStorage), но не более // того — это просто «продолжить с того же места», а не синхронизация между // вкладками/устройствами. key должен быть уникальным на раздел (см. вызовы в // RequestsTableView/SearchView), иначе значения разных таблиц перепишут друг друга. function readStored(storageKey: string): string { try { return window.localStorage.getItem(storageKey) || ''; } catch { return ''; } } export function usePersistedQuery(key: string): [string, (value: string) => void] { const storageKey = `rp-search-query:${key}`; const [value, setValue] = React.useState(() => readStored(storageKey)); // Компонент может продолжать жить, когда key поменялся: RequestsTableView — // это один и тот же элемент для вкладок «На согласовании» и «Мои заявки», // меняется только проп kind. Инициализатор useState при этом повторно НЕ // срабатывает, поэтому без перечитывания текст из одной вкладки оставался бы // на экране во второй и записывался уже под её ключ — выглядело бы так, будто // ключ у них общий. const prevKey = React.useRef(storageKey); React.useEffect(() => { if (prevKey.current === storageKey) return; prevKey.current = storageKey; setValue(readStored(storageKey)); }, [storageKey]); const setPersisted = React.useCallback( (next: string): void => { setValue(next); try { if (next) { window.localStorage.setItem(storageKey, next); } else { window.localStorage.removeItem(storageKey); } } catch { // localStorage недоступен (приватный режим и т.п.) — просто не сохраняем. } }, [storageKey] ); return [value, setPersisted]; } // Задержка перед тем, как введённый текст уйдёт в запрос. Без неё поиск // срабатывает на КАЖДОЕ нажатие клавиши: «согласование» — это 12 полных циклов // (Search + дочитывание через REST по каждому типу заявок), из которых нужен // только последний. Заодно снимает часть нагрузки, из-за которой SharePoint // начинает throttling'ить (429). const SEARCH_DEBOUNCE_MS = 450; // Значение, отстающее от переданного на SEARCH_DEBOUNCE_MS: в поле ввода текст // меняется сразу (без «залипания»), а в запрос уходит только когда пользователь // перестал печатать. Пустая строка проходит без задержки — очистка поиска // должна возвращать полный список мгновенно. export function useDebouncedQuery(value: string, delayMs: number = SEARCH_DEBOUNCE_MS): string { const [debounced, setDebounced] = React.useState(value); React.useEffect(() => { if (!value) { setDebounced(''); return undefined; } const timer = window.setTimeout(() => setDebounced(value), delayMs); return () => window.clearTimeout(timer); }, [value, delayMs]); return debounced; }