2025-08-12 09:39:09 +00:00
|
|
|
|
import { RouteDto } from '@/proxy/routes/models'
|
2025-06-28 21:34:28 +00:00
|
|
|
|
import { lazy } from 'react'
|
2025-10-30 19:23:59 +00:00
|
|
|
|
import { useComponents } from '@/contexts/ComponentContext'
|
2025-06-28 21:34:28 +00:00
|
|
|
|
|
|
|
|
|
|
// Tüm view bileşenlerini import et (vite özel)
|
2025-08-12 09:46:32 +00:00
|
|
|
|
// 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'])
|
2025-06-28 21:34:28 +00:00
|
|
|
|
|
|
|
|
|
|
const lazyComponentCache = new Map<string, React.LazyExoticComponent<React.ComponentType<any>>>()
|
|
|
|
|
|
|
2025-10-30 19:23:59 +00:00
|
|
|
|
// ComponentPath'in fiziksel mi yoksa dinamik mi olduğunu belirle
|
|
|
|
|
|
function isPhysicalComponent(componentPath: string): boolean {
|
|
|
|
|
|
// @ ile başlayan path'ler fiziksel dosya yolu
|
|
|
|
|
|
// Başka bir kural: dynamic: ile başlayan path'ler dinamik
|
|
|
|
|
|
return componentPath.startsWith('@/') || componentPath.startsWith('../')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function isDynamicComponent(componentPath: string): boolean {
|
|
|
|
|
|
// dynamic: ile başlayan path'ler dinamik komponent
|
|
|
|
|
|
return componentPath.startsWith('dynamic:')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Fiziksel komponent yükleme (mevcut mantık)
|
|
|
|
|
|
function loadPhysicalComponent(componentPath: string) {
|
2025-06-28 21:34:28 +00:00
|
|
|
|
const cleanedPath = componentPath.replace(/^@\//, '')
|
|
|
|
|
|
const fullPath = `../${cleanedPath}.tsx`
|
|
|
|
|
|
|
|
|
|
|
|
if (lazyComponentCache.has(fullPath)) {
|
2025-10-30 19:23:59 +00:00
|
|
|
|
// console.log(`Physical component loaded from cache: ${fullPath}`)
|
2025-06-28 21:34:28 +00:00
|
|
|
|
return lazyComponentCache.get(fullPath)!
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const loader = modules[fullPath]
|
|
|
|
|
|
if (!loader) {
|
2025-10-30 19:23:59 +00:00
|
|
|
|
console.error(`Physical component not found for path: ${fullPath}`)
|
|
|
|
|
|
throw new Error(`Physical component not found for path: ${fullPath}`)
|
2025-06-28 21:34:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const LazyComponent = lazy(loader as () => Promise<{ default: React.ComponentType<any> }>)
|
|
|
|
|
|
lazyComponentCache.set(fullPath, LazyComponent)
|
|
|
|
|
|
return LazyComponent
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 19:23:59 +00:00
|
|
|
|
// Dinamik komponent yükleme (yeni mantık)
|
|
|
|
|
|
function loadDynamicComponent(
|
|
|
|
|
|
componentPath: string,
|
|
|
|
|
|
registeredComponents: Record<string, React.ComponentType<unknown>>,
|
|
|
|
|
|
renderComponent?: (name: string, props?: any) => React.ReactNode,
|
|
|
|
|
|
isComponentRegistered?: (name: string) => boolean
|
|
|
|
|
|
) {
|
|
|
|
|
|
const componentName = componentPath.replace('dynamic:', '')
|
|
|
|
|
|
|
|
|
|
|
|
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[componentName]
|
|
|
|
|
|
|
|
|
|
|
|
// Eğer manuel registered'da yoksa, database compiled komponentleri kontrol et
|
|
|
|
|
|
if (!DynamicComponent && isComponentRegistered && renderComponent && isComponentRegistered(componentName)) {
|
|
|
|
|
|
// console.log(`Database component found: ${componentName}`)
|
|
|
|
|
|
// Database komponentini wrapper ile kullan
|
|
|
|
|
|
DynamicComponent = (props: any) => renderComponent(componentName, props) as React.ReactElement
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!DynamicComponent) {
|
|
|
|
|
|
console.error(`Dynamic component not found: ${componentName}`)
|
|
|
|
|
|
console.log('Available registered components:', Object.keys(registeredComponents))
|
|
|
|
|
|
if (isComponentRegistered) {
|
|
|
|
|
|
console.log('Database component registry available - checking...')
|
|
|
|
|
|
}
|
|
|
|
|
|
throw new Error(`Dynamic component not found: ${componentName}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// console.log(`Dynamic component loaded: ${componentName}`)
|
|
|
|
|
|
// Dinamik komponent için lazy wrapper oluştur
|
|
|
|
|
|
const LazyComponent = lazy(() => Promise.resolve({ default: DynamicComponent as React.ComponentType<any> }))
|
|
|
|
|
|
lazyComponentCache.set(componentPath, LazyComponent)
|
|
|
|
|
|
return LazyComponent
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function loadComponent(
|
|
|
|
|
|
componentPath: string,
|
|
|
|
|
|
registeredComponents?: Record<string, React.ComponentType<unknown>>,
|
|
|
|
|
|
renderComponent?: (name: string, props?: any) => React.ReactNode,
|
|
|
|
|
|
isComponentRegistered?: (name: string) => boolean
|
|
|
|
|
|
) {
|
|
|
|
|
|
if (isPhysicalComponent(componentPath)) {
|
|
|
|
|
|
return loadPhysicalComponent(componentPath)
|
|
|
|
|
|
} else if (isDynamicComponent(componentPath)) {
|
|
|
|
|
|
if (!registeredComponents) {
|
|
|
|
|
|
throw new Error('Registered components required for dynamic component loading')
|
|
|
|
|
|
}
|
|
|
|
|
|
return loadDynamicComponent(componentPath, registeredComponents, renderComponent, isComponentRegistered)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// Backward compatibility: varsayılan olarak fiziksel komponent kabul et
|
|
|
|
|
|
return loadPhysicalComponent(componentPath)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-28 21:34:28 +00:00
|
|
|
|
// React Router için uygun bir route tipi
|
|
|
|
|
|
export interface DynamicReactRoute {
|
2025-08-12 09:39:09 +00:00
|
|
|
|
key: string
|
|
|
|
|
|
path: string
|
2025-10-30 19:23:59 +00:00
|
|
|
|
getComponent: (
|
|
|
|
|
|
registeredComponents?: Record<string, React.ComponentType<unknown>>,
|
|
|
|
|
|
renderComponent?: (name: string, props?: any) => React.ReactNode,
|
|
|
|
|
|
isComponentRegistered?: (name: string) => boolean
|
|
|
|
|
|
) => React.LazyExoticComponent<React.ComponentType<any>>
|
2025-08-12 09:39:09 +00:00
|
|
|
|
routeType: string
|
|
|
|
|
|
authority?: string[]
|
2025-10-30 19:23:59 +00:00
|
|
|
|
componentPath: string
|
|
|
|
|
|
isPhysical: boolean
|
|
|
|
|
|
isDynamic: boolean
|
2025-06-28 21:34:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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,
|
2025-10-30 19:23:59 +00:00
|
|
|
|
getComponent: (registeredComponents, renderComponent, isComponentRegistered) =>
|
|
|
|
|
|
loadComponent(route.componentPath, registeredComponents, renderComponent, isComponentRegistered),
|
2025-06-28 21:34:28 +00:00
|
|
|
|
routeType: route.routeType,
|
|
|
|
|
|
authority: route.authority,
|
2025-10-30 19:23:59 +00:00
|
|
|
|
componentPath: route.componentPath,
|
|
|
|
|
|
isPhysical: isPhysicalComponent(route.componentPath),
|
|
|
|
|
|
isDynamic: isDynamicComponent(route.componentPath),
|
2025-08-12 09:39:09 +00:00
|
|
|
|
}))
|
2025-06-28 21:34:28 +00:00
|
|
|
|
}
|