Files
papercrate/frontend/src/hooks/documents/useTenantManager.ts
T
2025-11-23 00:11:18 +01:00

128 lines
3.6 KiB
TypeScript

import { MutableRefObject, useCallback } from 'react';
import type { NavigateFunction } from 'react-router-dom';
interface ApiClient {
get: (path: string) => Promise<{ data: unknown }>;
post: (path: string, body?: unknown) => Promise<{ data: any }>;
defaults: { headers: { common: Record<string, unknown> } };
}
interface TenantOption {
id?: string | number;
name?: string;
}
interface UseTenantManagerOptions {
apiClient: ApiClient;
appDispatch: (action: any) => void;
currentTenantId: string | number | null;
resetWorkspaceState: () => void;
setStatusMessage: (message: string, variant?: string) => void;
notifyApiError: (error: unknown, message: string) => void;
refreshTags: () => Promise<void>;
refreshCorrespondents: () => Promise<void>;
loadFolder: (folderId: string, options?: { preserveSearch?: boolean }) => Promise<void>;
handleDocumentsViewModeChange: (mode: string) => void;
navigate: NavigateFunction;
tokenRef?: MutableRefObject<string | null>;
tenantIdRef?: MutableRefObject<string | number | null>;
}
const useTenantManager = ({
apiClient,
appDispatch,
currentTenantId,
resetWorkspaceState,
setStatusMessage,
notifyApiError,
refreshTags,
refreshCorrespondents,
loadFolder,
handleDocumentsViewModeChange,
navigate,
tokenRef,
tenantIdRef,
}: UseTenantManagerOptions) => {
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) {
setStatusMessage('Switching tenant…', 'info');
}
if (refreshOnly) {
const { data } = await apiClient.get('/tenants');
appDispatch({
type: 'SET_TENANTS',
tenants: Array.isArray(data) ? data : [],
});
return;
}
const { data } = await apiClient.post('/auth/select-tenant', {
tenant_id: 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,
});
apiClient.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';
setStatusMessage(`Switched to ${tenantLabel}.`, 'info');
} catch (error) {
notifyApiError(error, 'Failed to switch tenant.');
}
},
[
apiClient,
appDispatch,
currentTenantId,
handleDocumentsViewModeChange,
loadFolder,
navigate,
notifyApiError,
refreshCorrespondents,
refreshTags,
resetWorkspaceState,
setStatusMessage,
tenantIdRef,
tokenRef,
],
);
return { handleTenantSelect };
};
export default useTenantManager;