sozsoft-platform/ui/src/routes/dynamicRouteLoader.tsx

131 lines
4.3 KiB
TypeScript
Raw Normal View History

2026-07-06 09:44:26 +00:00
import React, { lazy } from 'react'
2026-02-24 20:44:16 +00:00
import { RouteDto } from '@/proxy/routes/models'
// Tüm view bileşenlerini import et (vite özel)
// shared klasörü hariç, çünkü bu bileşenler genellikle başka yerlerde statik import ediliyor
const modules = import.meta.glob(['../views/**/*.tsx', '!../views/shared/**/*.tsx'])
const lazyComponentCache = new Map<string, React.LazyExoticComponent<React.ComponentType<any>>>()
// Fiziksel komponent yükleme (mevcut mantık)
function loadPhysicalComponent(componentPath: string) {
const cleanedPath = componentPath.replace(/^@\//, '')
const fullPath = `../${cleanedPath}.tsx`
if (lazyComponentCache.has(fullPath)) {
return lazyComponentCache.get(fullPath)!
}
const loader = modules[fullPath]
if (!loader) {
console.error(`Physical component not found for path: ${fullPath}`)
throw new Error(`Physical component not found for path: ${fullPath}`)
}
const LazyComponent = lazy(loader as () => Promise<{ default: React.ComponentType<any> }>)
lazyComponentCache.set(fullPath, LazyComponent)
return LazyComponent
}
// Dinamik komponent yükleme (yeni mantık)
function loadDynamicComponent(
componentPath: string,
2026-02-24 20:44:16 +00:00
registeredComponents: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean,
2026-02-24 20:44:16 +00:00
) {
2026-02-24 20:44:16 +00:00
if (lazyComponentCache.has(componentPath)) {
// console.log(`Dynamic component loaded from cache: ${componentName}`)
return lazyComponentCache.get(componentPath)!
}
// Önce manuel registered komponentleri kontrol et
let DynamicComponent = registeredComponents[componentPath]
2026-02-24 20:44:16 +00:00
// Eğer manuel registered'da yoksa, database compiled komponentleri kontrol et
if (
!DynamicComponent &&
isComponentRegistered &&
renderComponent &&
isComponentRegistered(componentPath)
) {
DynamicComponent = (props: any) => renderComponent(componentPath, props) as React.ReactElement
2026-02-24 20:44:16 +00:00
}
if (!DynamicComponent) {
if (isComponentRegistered) {
console.log('Database component registry available - checking...')
}
throw new Error(`Dynamic component not found: ${componentPath}`)
2026-02-24 20:44:16 +00:00
}
// console.log(`Dynamic component loaded: ${componentPath}`)
2026-02-24 20:44:16 +00:00
// Dinamik komponent için lazy wrapper oluştur
const LazyComponent = lazy(() =>
Promise.resolve({ default: DynamicComponent as React.ComponentType<any> }),
)
2026-02-24 20:44:16 +00:00
lazyComponentCache.set(componentPath, LazyComponent)
return LazyComponent
}
export function loadComponent(
componentType: string,
componentPath: string,
2026-02-24 20:44:16 +00:00
registeredComponents?: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean,
2026-02-24 20:44:16 +00:00
) {
if (componentType === 'normal') {
2026-02-24 20:44:16 +00:00
return loadPhysicalComponent(componentPath)
} else if (componentType === 'dynamic') {
2026-02-24 20:44:16 +00:00
if (!registeredComponents) {
throw new Error('Registered components required for dynamic component loading')
}
return loadDynamicComponent(
componentPath,
registeredComponents,
renderComponent,
isComponentRegistered,
)
2026-02-24 20:44:16 +00:00
} else {
// Backward compatibility: varsayılan olarak fiziksel komponent kabul et
return loadPhysicalComponent(componentPath)
}
}
// React Router için uygun bir route tipi
export interface DynamicReactRoute {
key: string
path: string
getComponent: (
registeredComponents?: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean,
2026-02-24 20:44:16 +00:00
) => React.LazyExoticComponent<React.ComponentType<any>>
routeType: string
authority?: string[]
componentType: string
2026-02-24 20:44:16 +00:00
componentPath: string
}
// API'den gelen route objesini, React Router için uygun hale getirir
export function mapDynamicRoutes(routes: RouteDto[]): DynamicReactRoute[] {
return routes.map((route) => ({
key: route.path,
path: route.path,
getComponent: (registeredComponents, renderComponent, isComponentRegistered) =>
loadComponent(
route.componentType,
route.componentPath,
registeredComponents,
renderComponent,
isComponentRegistered,
),
2026-02-24 20:44:16 +00:00
routeType: route.routeType,
authority: route.authority,
componentType: route.componentType,
2026-02-24 20:44:16 +00:00
componentPath: route.componentPath,
}))
}