@ibdop/platform-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/dist/components/ErrorBoundary.d.ts +68 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/Notification.d.ts +46 -0
- package/dist/components/Notification.d.ts.map +1 -0
- package/dist/components/VersionInfo.d.ts +18 -0
- package/dist/components/VersionInfo.d.ts.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +9 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useApi.d.ts +65 -0
- package/dist/hooks/useApi.d.ts.map +1 -0
- package/dist/hooks/useInfoData.d.ts +35 -0
- package/dist/hooks/useInfoData.d.ts.map +1 -0
- package/dist/hooks/usePermissions.d.ts +23 -0
- package/dist/hooks/usePermissions.d.ts.map +1 -0
- package/dist/hooks/useShellAuth.d.ts +23 -0
- package/dist/hooks/useShellAuth.d.ts.map +1 -0
- package/dist/hooks/useV1Config.d.ts +27 -0
- package/dist/hooks/useV1Config.d.ts.map +1 -0
- package/dist/index.cjs.js +18 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +1500 -0
- package/dist/index.umd.js +18 -0
- package/dist/services/api.d.ts +59 -0
- package/dist/services/api.d.ts.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/logger.d.ts +41 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/types/index.d.ts +178 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +90 -0
- package/src/components/ErrorBoundary.tsx +292 -0
- package/src/components/Notification.tsx +297 -0
- package/src/components/VersionInfo.tsx +271 -0
- package/src/components/index.ts +14 -0
- package/src/global.d.ts +40 -0
- package/src/hooks/index.ts +13 -0
- package/src/hooks/useApi.ts +314 -0
- package/src/hooks/useInfoData.ts +124 -0
- package/src/hooks/usePermissions.ts +88 -0
- package/src/hooks/useShellAuth.ts +145 -0
- package/src/hooks/useV1Config.ts +112 -0
- package/src/index.ts +17 -0
- package/src/services/api.ts +290 -0
- package/src/services/index.ts +9 -0
- package/src/services/logger.ts +71 -0
- package/src/types/index.ts +215 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useInfoData - Хук для загрузки информации о версии MF
|
|
3
|
+
*
|
|
4
|
+
* Загружает info.json с информацией о версии, Git commit, CI/CD данные
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
8
|
+
import type { InfoData } from '../types'
|
|
9
|
+
|
|
10
|
+
// Development mode flag
|
|
11
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Logger for useInfoData
|
|
15
|
+
*/
|
|
16
|
+
const logger = {
|
|
17
|
+
log: (...args: unknown[]) => {
|
|
18
|
+
if (isDev) console.log('[useInfoData]', ...args)
|
|
19
|
+
},
|
|
20
|
+
warn: (...args: unknown[]) => {
|
|
21
|
+
if (isDev) console.warn('[useInfoData]', ...args)
|
|
22
|
+
},
|
|
23
|
+
error: (...args: unknown[]) => {
|
|
24
|
+
console.error('[useInfoData]', ...args)
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Interface для props useInfoData
|
|
30
|
+
*/
|
|
31
|
+
interface UseInfoDataProps {
|
|
32
|
+
mfeName?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Interface для результата useInfoData
|
|
37
|
+
*/
|
|
38
|
+
interface UseInfoDataResult {
|
|
39
|
+
data: InfoData | null
|
|
40
|
+
isLoading: boolean
|
|
41
|
+
error: string | null
|
|
42
|
+
refetch: () => void
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Получить mfeName из props или window
|
|
47
|
+
*/
|
|
48
|
+
function getMfeName(propsMfeName?: string): string {
|
|
49
|
+
if (propsMfeName) return propsMfeName
|
|
50
|
+
|
|
51
|
+
// Try window.__MF_NAME__
|
|
52
|
+
if (typeof window !== 'undefined') {
|
|
53
|
+
const win = window as unknown as { __MF_NAME__?: string }
|
|
54
|
+
if (win.__MF_NAME__) return win.__MF_NAME__
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return 'unknown-mfe'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Централизованный хук для загрузки информации о версии MF
|
|
62
|
+
*
|
|
63
|
+
* @param props - { mfeName?: string } - опционально имя MF
|
|
64
|
+
* @returns { data, isLoading, error, refetch }
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```tsx
|
|
68
|
+
* const { data, isLoading, error } = useInfoData({ mfeName: '@ib-dop/mf-home' })
|
|
69
|
+
*
|
|
70
|
+
* if (isLoading) return <Loading />
|
|
71
|
+
* if (error) return <Error>{error}</Error>
|
|
72
|
+
*
|
|
73
|
+
* return <Badge>{data?.BUILD_VERSION}</Badge>
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export function useInfoData(props?: UseInfoDataProps): UseInfoDataResult {
|
|
77
|
+
const [data, setData] = useState<InfoData | null>(null)
|
|
78
|
+
const [isLoading, setIsLoading] = useState(true)
|
|
79
|
+
const [error, setError] = useState<string | null>(null)
|
|
80
|
+
|
|
81
|
+
const fetchInfo = useCallback(() => {
|
|
82
|
+
const mfeName = getMfeName(props?.mfeName)
|
|
83
|
+
|
|
84
|
+
// Normalize mfeName (remove @ib-dop/ prefix)
|
|
85
|
+
const normalizedName = mfeName.replace('@ib-dop/', '')
|
|
86
|
+
|
|
87
|
+
logger.log('Fetching info for:', normalizedName)
|
|
88
|
+
setIsLoading(true)
|
|
89
|
+
setError(null)
|
|
90
|
+
|
|
91
|
+
fetch(`/svc/${normalizedName}/info.json`)
|
|
92
|
+
.then((response) => {
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
95
|
+
}
|
|
96
|
+
return response.json()
|
|
97
|
+
})
|
|
98
|
+
.then((result) => {
|
|
99
|
+
logger.log('Info loaded successfully')
|
|
100
|
+
setData(result as InfoData)
|
|
101
|
+
})
|
|
102
|
+
.catch((err) => {
|
|
103
|
+
logger.error('Failed to load info:', err)
|
|
104
|
+
setError(err instanceof Error ? err.message : String(err))
|
|
105
|
+
})
|
|
106
|
+
.finally(() => {
|
|
107
|
+
setIsLoading(false)
|
|
108
|
+
})
|
|
109
|
+
}, [props?.mfeName])
|
|
110
|
+
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
fetchInfo()
|
|
113
|
+
}, [fetchInfo])
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
data,
|
|
117
|
+
isLoading,
|
|
118
|
+
error,
|
|
119
|
+
refetch: fetchInfo,
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Named exports
|
|
124
|
+
export type { UseInfoDataProps, UseInfoDataResult }
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePermissions - Хук для проверки прав доступа
|
|
3
|
+
*
|
|
4
|
+
* Предоставляет API для проверки прав пользователя на основе ролей
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useMemo } from 'react'
|
|
8
|
+
import { useShellAuth } from './useShellAuth'
|
|
9
|
+
import type { MfPermissionsConfig, MfPermissions } from '../types'
|
|
10
|
+
|
|
11
|
+
// Development mode flag
|
|
12
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Logger for usePermissions
|
|
16
|
+
*/
|
|
17
|
+
const logger = {
|
|
18
|
+
log: (...args: unknown[]) => {
|
|
19
|
+
if (isDev) console.log('[usePermissions]', ...args)
|
|
20
|
+
},
|
|
21
|
+
warn: (...args: unknown[]) => {
|
|
22
|
+
if (isDev) console.warn('[usePermissions]', ...args)
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Default permissions configuration
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_PERMISSIONS_CONFIG: MfPermissionsConfig = {
|
|
30
|
+
canView: ['all'] as string[],
|
|
31
|
+
canEdit: ['ibdop-user', 'ibdop-admin', 'ibdop-devops'] as string[],
|
|
32
|
+
canDelete: ['ibdop-admin', 'ibdop-devops'] as string[],
|
|
33
|
+
canAdmin: ['ibdop-admin'] as string[],
|
|
34
|
+
canViewSensitiveData: ['ibdop-admin', 'ibdop-devops'] as string[],
|
|
35
|
+
canExportData: ['ibdop-user'] as string[],
|
|
36
|
+
canManageUsers: ['ibdop-admin'] as string[],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Централизованный хук для проверки прав доступа
|
|
41
|
+
*
|
|
42
|
+
* @param config - конфигурация прав доступа (опционально)
|
|
43
|
+
* @returns MfPermissions - объект с правами доступа
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* const permissions = usePermissions()
|
|
48
|
+
*
|
|
49
|
+
* if (permissions.canAdmin) {
|
|
50
|
+
* return <AdminPanel />
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function usePermissions(config: Partial<MfPermissionsConfig> = {}): MfPermissions {
|
|
55
|
+
const auth = useShellAuth()
|
|
56
|
+
|
|
57
|
+
const mergedConfig = useMemo(() => ({
|
|
58
|
+
...DEFAULT_PERMISSIONS_CONFIG,
|
|
59
|
+
...config,
|
|
60
|
+
}), [config])
|
|
61
|
+
|
|
62
|
+
// Extract user roles
|
|
63
|
+
const userRoles = useMemo(() => {
|
|
64
|
+
const roles = auth.user?.profile?.realm_roles || auth.user?.profile?.roles || []
|
|
65
|
+
return Array.isArray(roles) ? roles : [roles]
|
|
66
|
+
}, [auth.user])
|
|
67
|
+
|
|
68
|
+
logger.log('User roles:', userRoles)
|
|
69
|
+
|
|
70
|
+
// Check if user has permission
|
|
71
|
+
const hasPermission = (requiredRoles: string[]): boolean => {
|
|
72
|
+
if (requiredRoles.includes('all')) return true
|
|
73
|
+
return requiredRoles.some(role => userRoles.includes(role))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
canView: hasPermission(mergedConfig.canView),
|
|
78
|
+
canEdit: hasPermission(mergedConfig.canEdit),
|
|
79
|
+
canDelete: hasPermission(mergedConfig.canDelete),
|
|
80
|
+
canAdmin: hasPermission(mergedConfig.canAdmin),
|
|
81
|
+
canViewSensitiveData: hasPermission(mergedConfig.canViewSensitiveData),
|
|
82
|
+
canExportData: hasPermission(mergedConfig.canExportData),
|
|
83
|
+
canManageUsers: hasPermission(mergedConfig.canManageUsers),
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Named exports
|
|
88
|
+
export type { MfPermissionsConfig }
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useShellAuth - Хук для получения состояния авторизации из shell
|
|
3
|
+
*
|
|
4
|
+
* Паттерн: MF подключается к shell через window.__SHELL_AUTH_INSTANCE__
|
|
5
|
+
* и ожидает события 'shell-auth-ready' если auth ещё не готов.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useEffect, useState, useCallback, useRef } from 'react'
|
|
9
|
+
import type { ShellAuth } from '../types'
|
|
10
|
+
|
|
11
|
+
// Development mode flag
|
|
12
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Logger for useShellAuth
|
|
16
|
+
*/
|
|
17
|
+
const logger = {
|
|
18
|
+
log: (...args: unknown[]) => {
|
|
19
|
+
if (isDev) console.log('[useShellAuth]', ...args)
|
|
20
|
+
},
|
|
21
|
+
warn: (...args: unknown[]) => {
|
|
22
|
+
if (isDev) console.warn('[useShellAuth]', ...args)
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Получить auth из window globals
|
|
28
|
+
*/
|
|
29
|
+
function getAuth(): ShellAuth | null {
|
|
30
|
+
if (typeof window === 'undefined') return null
|
|
31
|
+
|
|
32
|
+
// Try __SHELL_AUTH_INSTANCE__ first
|
|
33
|
+
const win = window as unknown as { __SHELL_AUTH_INSTANCE__?: ShellAuth }
|
|
34
|
+
if (win.__SHELL_AUTH_INSTANCE__) {
|
|
35
|
+
return win.__SHELL_AUTH_INSTANCE__
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Try __SHELL_AUTH__ format
|
|
39
|
+
const win2 = window as unknown as { __SHELL_AUTH__?: { authInstance?: ShellAuth } }
|
|
40
|
+
if (win2.__SHELL_AUTH__?.authInstance) {
|
|
41
|
+
return win2.__SHELL_AUTH__.authInstance
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Централизованный хук для получения состояния авторизации из shell
|
|
49
|
+
*
|
|
50
|
+
* @returns ShellAuth - объект с состоянием авторизации
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* const auth = useShellAuth()
|
|
55
|
+
*
|
|
56
|
+
* if (auth.isLoading) return <Loading />
|
|
57
|
+
* if (!auth.isAuthenticated) return <Login />
|
|
58
|
+
*
|
|
59
|
+
* return <div>{auth.user?.profile?.preferred_username}</div>
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function useShellAuth(): ShellAuth {
|
|
63
|
+
const [auth, setAuth] = useState<ShellAuth | null>(null)
|
|
64
|
+
const [isLoading, setIsLoading] = useState(true)
|
|
65
|
+
const attemptsRef = useRef(0)
|
|
66
|
+
const maxAttempts = 20 // 10 seconds max wait (20 * 500ms)
|
|
67
|
+
|
|
68
|
+
const getAuthState = useCallback((): ShellAuth | null => {
|
|
69
|
+
return getAuth()
|
|
70
|
+
}, [])
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
// Immediate check for auth
|
|
74
|
+
const immediateAuth = getAuthState()
|
|
75
|
+
if (immediateAuth) {
|
|
76
|
+
logger.log('Auth found immediately')
|
|
77
|
+
setAuth(immediateAuth)
|
|
78
|
+
setIsLoading(false)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Subscribe to auth ready event
|
|
83
|
+
const handleAuthReady = (event: CustomEvent<ShellAuth>) => {
|
|
84
|
+
logger.log('Auth ready via event')
|
|
85
|
+
setAuth(event.detail)
|
|
86
|
+
setIsLoading(false)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Fallback polling with limit
|
|
90
|
+
const interval = setInterval(() => {
|
|
91
|
+
attemptsRef.current++
|
|
92
|
+
const foundAuth = getAuthState()
|
|
93
|
+
|
|
94
|
+
if (foundAuth) {
|
|
95
|
+
logger.log('Auth found via polling, attempts:', attemptsRef.current)
|
|
96
|
+
setAuth(foundAuth)
|
|
97
|
+
setIsLoading(false)
|
|
98
|
+
clearInterval(interval)
|
|
99
|
+
} else if (attemptsRef.current >= maxAttempts) {
|
|
100
|
+
logger.warn('Auth timeout after', maxAttempts, 'attempts')
|
|
101
|
+
setIsLoading(false)
|
|
102
|
+
clearInterval(interval)
|
|
103
|
+
}
|
|
104
|
+
}, 500)
|
|
105
|
+
|
|
106
|
+
window.addEventListener('shell-auth-ready', handleAuthReady as EventListener)
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
clearInterval(interval)
|
|
110
|
+
window.removeEventListener('shell-auth-ready', handleAuthReady as EventListener)
|
|
111
|
+
}
|
|
112
|
+
}, [getAuthState])
|
|
113
|
+
|
|
114
|
+
// Fallback auth when shell auth is not available
|
|
115
|
+
const fallbackAuth: ShellAuth = {
|
|
116
|
+
user: null,
|
|
117
|
+
isAuthenticated: false,
|
|
118
|
+
isLoading: isLoading,
|
|
119
|
+
signinRedirect: async () => {
|
|
120
|
+
logger.log('Redirecting to login')
|
|
121
|
+
const shellAuth = getAuth()
|
|
122
|
+
if (shellAuth?.signinRedirect) {
|
|
123
|
+
await shellAuth.signinRedirect()
|
|
124
|
+
} else {
|
|
125
|
+
if (typeof window !== 'undefined') {
|
|
126
|
+
window.location.href = '/'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
removeUser: async () => {
|
|
131
|
+
const shellAuth = getAuth()
|
|
132
|
+
if (shellAuth?.removeUser) {
|
|
133
|
+
await shellAuth.removeUser()
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const result = auth || fallbackAuth
|
|
139
|
+
logger.log('Auth result:', { isAuthenticated: result.isAuthenticated, isLoading: result.isLoading })
|
|
140
|
+
|
|
141
|
+
return result
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Named exports for specific helpers
|
|
145
|
+
export { getAuth }
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useV1Config - Хук для загрузки конфигурации из sessionStorage
|
|
3
|
+
*
|
|
4
|
+
* Загружает V1 конфигурацию, которая используется для OIDC и других настроек
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect } from 'react'
|
|
8
|
+
import type { V1ConfigData } from '../types'
|
|
9
|
+
|
|
10
|
+
// Development mode flag
|
|
11
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Logger for useV1Config
|
|
15
|
+
*/
|
|
16
|
+
const logger = {
|
|
17
|
+
log: (...args: unknown[]) => {
|
|
18
|
+
if (isDev) console.log('[useV1Config]', ...args)
|
|
19
|
+
},
|
|
20
|
+
warn: (...args: unknown[]) => {
|
|
21
|
+
if (isDev) console.warn('[useV1Config]', ...args)
|
|
22
|
+
},
|
|
23
|
+
error: (...args: unknown[]) => {
|
|
24
|
+
console.error('[useV1Config]', ...args)
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Default config for fallback
|
|
30
|
+
*/
|
|
31
|
+
const DEFAULT_CONFIG: V1ConfigData = {
|
|
32
|
+
authority: '',
|
|
33
|
+
client_id: '',
|
|
34
|
+
environment: 'development',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Interface для результата useV1Config
|
|
39
|
+
*/
|
|
40
|
+
interface UseV1ConfigResult {
|
|
41
|
+
data: V1ConfigData | null
|
|
42
|
+
isLoading: boolean
|
|
43
|
+
error: string | null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Централизованный хук для загрузки конфигурации из sessionStorage
|
|
48
|
+
*
|
|
49
|
+
* @returns { data, isLoading, error }
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* const { data, isLoading, error } = useV1Config()
|
|
54
|
+
*
|
|
55
|
+
* if (isLoading) return null
|
|
56
|
+
* if (error || !data) return <Error>{error}</Error>
|
|
57
|
+
*
|
|
58
|
+
* return <ConfigDisplay config={data} />
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export function useV1Config(): UseV1ConfigResult {
|
|
62
|
+
const [data, setData] = useState<V1ConfigData | null>(null)
|
|
63
|
+
const [isLoading, setIsLoading] = useState(true)
|
|
64
|
+
const [error, setError] = useState<string | null>(null)
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
const fetchConfig = () => {
|
|
68
|
+
// Check if sessionStorage is available
|
|
69
|
+
if (typeof sessionStorage === 'undefined') {
|
|
70
|
+
logger.warn('sessionStorage not available')
|
|
71
|
+
setError('sessionStorage not available')
|
|
72
|
+
setData(DEFAULT_CONFIG)
|
|
73
|
+
setIsLoading(false)
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const storedConfig = sessionStorage.getItem('config')
|
|
79
|
+
|
|
80
|
+
if (storedConfig) {
|
|
81
|
+
const parsed = JSON.parse(storedConfig)
|
|
82
|
+
setData({ ...DEFAULT_CONFIG, ...parsed })
|
|
83
|
+
setError(null)
|
|
84
|
+
logger.log('Config loaded successfully')
|
|
85
|
+
} else {
|
|
86
|
+
// Config not found - use defaults instead of error
|
|
87
|
+
setData(DEFAULT_CONFIG)
|
|
88
|
+
setError('Config not found in sessionStorage')
|
|
89
|
+
logger.warn('Config not found in sessionStorage')
|
|
90
|
+
}
|
|
91
|
+
} catch (err) {
|
|
92
|
+
// Parse error - use defaults
|
|
93
|
+
logger.error('Error parsing config:', err)
|
|
94
|
+
setData(DEFAULT_CONFIG)
|
|
95
|
+
setError('Error parsing config')
|
|
96
|
+
} finally {
|
|
97
|
+
setIsLoading(false)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fetchConfig()
|
|
102
|
+
}, [])
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
data,
|
|
106
|
+
isLoading,
|
|
107
|
+
error,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Named exports
|
|
112
|
+
export type { UseV1ConfigResult }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ib-dop/platform-kit - Platform Development Kit for Microfrontends
|
|
3
|
+
*
|
|
4
|
+
* Unified toolkit for all microfrontends in the IB DOP Platform
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Types
|
|
8
|
+
export * from './types'
|
|
9
|
+
|
|
10
|
+
// Hooks
|
|
11
|
+
export * from './hooks'
|
|
12
|
+
|
|
13
|
+
// Components
|
|
14
|
+
export * from './components'
|
|
15
|
+
|
|
16
|
+
// Services
|
|
17
|
+
export * from './services'
|