@dbs-portal/module-tenant-management
Version:
Tenant management and multi-tenancy support module
173 lines • 5.99 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
/**
* Tenant Context Hook for Multi-tenancy Support
*/
import React, { createContext, useContext, useState, useEffect } from 'react';
import { useTenantLookup } from './use-tenants';
// Create the context
const TenantContextInstance = createContext(undefined);
/**
* Tenant Provider Component
*/
export const TenantProvider = ({ children, defaultTenantId, onTenantChange }) => {
const [currentTenant, setCurrentTenant] = useState();
const [isLoading, setIsLoading] = useState(true);
const { data: availableTenants = [], refetch: refetchTenants } = useTenantLookup();
// Initialize current tenant
useEffect(() => {
if (availableTenants.length > 0 && !currentTenant) {
// Try to get tenant from localStorage first
const storedTenantId = localStorage.getItem('dbs-portal-current-tenant');
let initialTenant;
if (storedTenantId) {
initialTenant = availableTenants.find(t => t.id === storedTenantId);
}
if (!initialTenant && defaultTenantId) {
initialTenant = availableTenants.find(t => t.id === defaultTenantId);
}
if (!initialTenant && availableTenants.length > 0) {
initialTenant = availableTenants[0];
}
if (initialTenant) {
// Convert TenantLookupDto to Tenant (simplified)
const tenant = {
...initialTenant,
connectionString: '',
features: [],
settings: {},
statistics: {
userCount: 0,
activeUserCount: 0,
storageUsed: 0,
createdThisMonth: 0,
loginCount: 0,
apiCallCount: 0
},
createdAt: new Date(),
updatedAt: new Date()
};
setCurrentTenant(tenant);
localStorage.setItem('dbs-portal-current-tenant', tenant.id);
onTenantChange?.(tenant);
}
}
setIsLoading(false);
}, [availableTenants, currentTenant, defaultTenantId, onTenantChange]);
/**
* Switch to a different tenant
*/
const switchTenant = async (tenantId) => {
setIsLoading(true);
try {
const tenantLookup = availableTenants.find(t => t.id === tenantId);
if (!tenantLookup) {
throw new Error(`Tenant with ID ${tenantId} not found`);
}
// Convert TenantLookupDto to Tenant (simplified)
const tenant = {
...tenantLookup,
connectionString: '',
features: [],
settings: {},
statistics: {
userCount: 0,
activeUserCount: 0,
storageUsed: 0,
createdThisMonth: 0,
loginCount: 0,
apiCallCount: 0
},
createdAt: new Date(),
updatedAt: new Date()
};
setCurrentTenant(tenant);
localStorage.setItem('dbs-portal-current-tenant', tenantId);
onTenantChange?.(tenant);
// Optionally reload the page to ensure all tenant-specific data is refreshed
// window.location.reload()
}
catch (error) {
console.error('Failed to switch tenant:', error);
throw error;
}
finally {
setIsLoading(false);
}
};
/**
* Refresh available tenants
*/
const refreshTenants = async () => {
await refetchTenants();
};
const contextValue = {
currentTenant: currentTenant || undefined,
availableTenants,
isLoading,
switchTenant,
refreshTenants
};
return (_jsx(TenantContextInstance.Provider, { value: contextValue, children: children }));
};
/**
* Hook to use tenant context
*/
export function useTenantContext() {
const context = useContext(TenantContextInstance);
if (context === undefined) {
throw new Error('useTenantContext must be used within a TenantProvider');
}
return context;
}
/**
* Hook to get current tenant
*/
export function useCurrentTenant() {
const { currentTenant, isLoading } = useTenantContext();
return { currentTenant, isLoading };
}
/**
* Hook to switch tenant
*/
export function useTenantSwitcher() {
const { switchTenant, availableTenants, currentTenant, isLoading } = useTenantContext();
return {
switchTenant,
availableTenants,
currentTenant,
isLoading,
canSwitch: availableTenants.length > 1
};
}
/**
* Higher-order component to ensure tenant context
*/
export function withTenantContext(Component) {
return function WithTenantContextComponent(props) {
const { currentTenant } = useCurrentTenant();
// If tenantId is provided as prop, use it; otherwise use current tenant
const effectiveTenantId = props.tenantId || currentTenant?.id;
if (!effectiveTenantId) {
return _jsx("div", { children: "No tenant selected" });
}
return _jsx(Component, { ...props });
};
}
/**
* Hook to ensure tenant is selected
*/
export function useRequireTenant() {
const { currentTenant, isLoading } = useCurrentTenant();
if (isLoading) {
return { tenant: null, isLoading: true, error: null };
}
if (!currentTenant) {
return {
tenant: null,
isLoading: false,
error: new Error('No tenant selected. Please select a tenant to continue.')
};
}
return { tenant: currentTenant, isLoading: false, error: null };
}
//# sourceMappingURL=use-tenant-context.js.map