117 lines
3.3 KiB
TypeScript
117 lines
3.3 KiB
TypeScript
import { MutableRefObject, useCallback } from 'react';
|
|
import type { NavigateFunction } from 'react-router-dom';
|
|
import type { FolderId, TenantId } from '../../types/identifiers';
|
|
import { useStatusToast } from '../../lib/context/StatusToastContext';
|
|
|
|
import { api, listTenants, switchTenant } from '../../lib/api/apiClient';
|
|
|
|
interface TenantOption {
|
|
id?: TenantId;
|
|
name?: string;
|
|
}
|
|
|
|
import useNotifyApiError from '../../hooks/useNotifyApiError';
|
|
|
|
interface UseTenantManagerOptions {
|
|
appDispatch: (action: any) => void;
|
|
currentTenantId: TenantId | null;
|
|
resetWorkspaceState: () => void;
|
|
refreshTags: () => Promise<void>;
|
|
refreshCorrespondents: () => Promise<void>;
|
|
loadFolder: (folderId: FolderId, options?: { preserveSearch?: boolean }) => Promise<void>;
|
|
handleDocumentsViewModeChange: (mode: string) => void;
|
|
navigate: NavigateFunction;
|
|
tokenRef?: MutableRefObject<string | null>;
|
|
tenantIdRef?: MutableRefObject<TenantId | null>;
|
|
}
|
|
|
|
const useTenantManager = ({
|
|
appDispatch,
|
|
currentTenantId,
|
|
resetWorkspaceState,
|
|
refreshTags,
|
|
refreshCorrespondents,
|
|
loadFolder,
|
|
handleDocumentsViewModeChange,
|
|
navigate,
|
|
tokenRef,
|
|
tenantIdRef,
|
|
}: UseTenantManagerOptions) => {
|
|
const { showToast } = useStatusToast();
|
|
const notifyApiError = useNotifyApiError();
|
|
const handleTenantSelect = useCallback(
|
|
async (tenantOption: TenantOption | null, { refreshOnly = false }: { refreshOnly?: boolean } = {}) => {
|
|
const requestedTenantId = tenantOption?.id ?? null;
|
|
if (!refreshOnly && (!requestedTenantId || requestedTenantId === currentTenantId)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
if (refreshOnly) {
|
|
const data = await listTenants();
|
|
appDispatch({
|
|
type: 'SET_TENANTS',
|
|
tenants: data,
|
|
});
|
|
return;
|
|
}
|
|
|
|
const data = await switchTenant(requestedTenantId);
|
|
if (!data?.access_token) {
|
|
throw new Error('Missing access token in tenant switch response.');
|
|
}
|
|
|
|
appDispatch({ type: 'LOGOUT' });
|
|
resetWorkspaceState();
|
|
|
|
appDispatch({
|
|
type: 'LOGIN_SUCCESS',
|
|
token: data.access_token,
|
|
tenant: data.tenant || null,
|
|
});
|
|
|
|
api.defaults.headers.common.Authorization = `Bearer ${data.access_token}`;
|
|
if (tokenRef) {
|
|
tokenRef.current = data.access_token;
|
|
}
|
|
if (tenantIdRef) {
|
|
tenantIdRef.current = data?.tenant?.id ?? null;
|
|
}
|
|
|
|
if (Array.isArray(data?.tenants)) {
|
|
appDispatch({ type: 'SET_TENANTS', tenants: data.tenants });
|
|
}
|
|
|
|
handleDocumentsViewModeChange('list');
|
|
navigate('/documents', { replace: true });
|
|
|
|
await Promise.all([refreshTags(), refreshCorrespondents()]);
|
|
await loadFolder('root', { preserveSearch: false });
|
|
|
|
const tenantLabel = data?.tenant?.name || data?.tenant?.id || 'tenant';
|
|
showToast(`Switched to ${tenantLabel}.`, 'info');
|
|
} catch (error) {
|
|
notifyApiError(error, 'Failed to switch tenant.');
|
|
}
|
|
},
|
|
[
|
|
appDispatch,
|
|
currentTenantId,
|
|
handleDocumentsViewModeChange,
|
|
loadFolder,
|
|
navigate,
|
|
notifyApiError,
|
|
refreshCorrespondents,
|
|
refreshTags,
|
|
resetWorkspaceState,
|
|
showToast,
|
|
tenantIdRef,
|
|
tokenRef,
|
|
],
|
|
);
|
|
|
|
return { handleTenantSelect };
|
|
};
|
|
|
|
export default useTenantManager;
|