import '@pnp/sp/fields'; import { getSP } from '../pnp/pnpjs'; /** Ответ SP по колонке Choice: массив в nometadata, { results } — в verbose-формате OData. */ interface IChoiceFieldResponse { Choices?: string[] | { results?: string[] }; } // Кеш на время жизни страницы: варианты администратор меняет редко, а форму за // сессию открывают по нескольку раз — повторно ходить в SP незачем. Хранится // промис, чтобы параллельные вызовы (три поля одной формы) не дублировали запрос. const cache = new Map>(); /** * Варианты колонки Choice/MultiChoice прямо из списка SharePoint. * * Колонка списка — единственный источник вариантов: чтобы добавить пункт, * достаточно дописать его в параметрах столбца, без правки кода и деплоя. */ export function getFieldChoices(listTitle: string, internalName: string): Promise { const key = `${listTitle}|${internalName}`.toLowerCase(); const cached = cache.get(key); if (cached) return cached; const request = loadFieldChoices(listTitle, internalName); // Сбой не кешируем — при следующем открытии формы запрос уйдёт заново. request.catch(() => cache.delete(key)); cache.set(key, request); return request; } async function loadFieldChoices(listTitle: string, internalName: string): Promise { const field = (await getSP() .web.lists.getByTitle(listTitle) .fields.getByInternalNameOrTitle(internalName) .select('Choices')()) as IChoiceFieldResponse; const choices = Array.isArray(field.Choices) ? field.Choices : field.Choices?.results || []; return choices.filter((choice) => choice.trim() !== ''); }