637e51d7f9
Tests / frontend-test (push) Successful in 1m24s
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/23
54 lines
2.4 KiB
TypeScript
54 lines
2.4 KiB
TypeScript
import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';
|
|
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
|
import { APPROVAL_API_CLIENT_ID, DICTIONARY_API_BASE_URL } from '../config';
|
|
import { IStorageLike, readCachedCompanies, writeCachedCompanies } from './companiesCache';
|
|
import { ICompany } from './models/ICompany';
|
|
|
|
// GET /Dictionary/Companies — справочник компаний, ответ — плоский массив
|
|
// { Id, Name, Bin } (без обёртки, как /Dictionary/Departments).
|
|
async function fetchCompanies(context: WebPartContext): Promise<ICompany[]> {
|
|
const client = await context.aadHttpClientFactory.getClient(APPROVAL_API_CLIENT_ID);
|
|
const response: HttpClientResponse = await client.get(
|
|
`${DICTIONARY_API_BASE_URL}/Dictionary/Companies`,
|
|
AadHttpClient.configurations.v1
|
|
);
|
|
if (!response.ok) {
|
|
throw new Error(`Dictionary/Companies: ${response.status} ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
/** localStorage, если он есть: в некоторых режимах браузера обращение к нему бросает исключение. */
|
|
function browserStorage(): IStorageLike | undefined {
|
|
try {
|
|
return window.localStorage;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
async function loadCompanies(context: WebPartContext): Promise<ICompany[]> {
|
|
const storage = browserStorage();
|
|
const cached = storage ? readCachedCompanies(storage, Date.now()) : undefined;
|
|
if (cached) return cached;
|
|
|
|
const fresh = await fetchCompanies(context);
|
|
if (storage) writeCachedCompanies(storage, fresh, Date.now());
|
|
return fresh;
|
|
}
|
|
|
|
// Справочник живёт в localStorage 4 часа (см. companiesCache.ts) — между перезагрузками страницы
|
|
// к API не ходим. Поверх этого один промис на сессию: параллельные вызовы делят один запрос и не
|
|
// читают хранилище заново (как в departments.service). Ошибку не кешируем — следующий вызов
|
|
// попробует ещё раз.
|
|
let cache: Promise<ICompany[]> | undefined;
|
|
export function getCompanies(context: WebPartContext): Promise<ICompany[]> {
|
|
if (!cache) {
|
|
cache = loadCompanies(context).catch((e) => {
|
|
cache = undefined;
|
|
throw e;
|
|
});
|
|
}
|
|
return cache;
|
|
}
|