Files
tnsu-approval-route/frontend/src/webparts/approvalAdmin/components/ApprovalAdmin.tsx
T
2026-08-14 14:51:48 +05:00

91 lines
3.4 KiB
TypeScript

import * as React from 'react';
import styles from './ApprovalAdmin.module.scss';
import type { IApprovalAdminProps } from './IApprovalAdminProps';
import { AdminApp } from './app/AdminApp';
import { ApprovalRouteApi } from '../services/api';
import { AadApiHttpClient, IHttpClient } from '../services/httpClient';
import { PortalDictionaryClient } from '../services/portalDictionary';
import { SharePointListsClient } from '../services/sharePointLists';
import { RequestManageService } from '../services/requestManageService';
import { texts } from '../texts';
const FONTS_LINK_ID = 'tnsu-approval-admin-fonts';
function ensureFontsLoaded(): void {
if (typeof document === 'undefined' || document.getElementById(FONTS_LINK_ID)) return;
const link = document.createElement('link');
link.id = FONTS_LINK_ID;
link.rel = 'stylesheet';
link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lora:wght@500;600;700&display=swap';
document.head.appendChild(link);
}
async function createHttpClient(props: IApprovalAdminProps): Promise<IHttpClient> {
const aadClient = await props.context.aadHttpClientFactory.getClient(props.aadResourceId);
return new AadApiHttpClient(aadClient, props.apiBaseUrl);
}
const ApprovalAdmin: React.FC<IApprovalAdminProps> = props => {
const [api, setApi] = React.useState<ApprovalRouteApi | undefined>();
const [dictionary, setDictionary] = React.useState<PortalDictionaryClient | undefined>();
const [error, setError] = React.useState<string | undefined>();
const sharePoint = React.useMemo(() => new SharePointListsClient(props.context), [props.context]);
const requestManage = React.useMemo(() => new RequestManageService(props.context), [props.context]);
React.useEffect(() => {
ensureFontsLoaded();
}, []);
React.useEffect(() => {
let cancelled = false;
setApi(undefined);
setError(undefined);
createHttpClient(props)
.then(client => { if (!cancelled) setApi(new ApprovalRouteApi(client)); })
.catch((e: Error) => { if (!cancelled) setError(e.message); });
return () => { cancelled = true; };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.apiBaseUrl, props.aadResourceId]);
React.useEffect(() => {
let cancelled = false;
setDictionary(undefined);
props.context.aadHttpClientFactory
.getClient(props.aadResourceId)
.then(client => {
if (!cancelled) setDictionary(new PortalDictionaryClient(client, props.portalBaseUrl));
})
.catch(() => { /* экран маршрутов покажет ошибку загрузки справочника */ });
return () => { cancelled = true; };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.aadResourceId, props.portalBaseUrl]);
return (
<section className={styles.approvalAdmin}>
{error && (
<div className={styles.stateBox}>
{texts.app.connectFailed(error)}
<br />
{texts.app.connectHint}
</div>
)}
{!error && !api && <div className={styles.stateBox}>{texts.app.connecting}</div>}
{api && (
<AdminApp
api={api}
dictionary={dictionary}
sharePoint={sharePoint}
requestManage={requestManage}
currentUserEmail={props.context.pageContext.user.email}
/>
)}
</section>
);
};
export default ApprovalAdmin;