835 lines
24 KiB
JavaScript
835 lines
24 KiB
JavaScript
import { useContext, useState, useEffect } from 'react'
|
||
import {
|
||
Descriptions,
|
||
Button,
|
||
Typography,
|
||
Flex,
|
||
Space,
|
||
Dropdown,
|
||
message,
|
||
Tag,
|
||
Input,
|
||
InputNumber,
|
||
Select
|
||
} from 'antd'
|
||
import ReloadIcon from '../../Icons/ReloadIcon.jsx'
|
||
import CloudIcon from '../../Icons/CloudIcon.jsx'
|
||
import { ApiServerContext } from '../context/ApiServerContext.jsx'
|
||
import BoolDisplay from '../common/BoolDisplay.jsx'
|
||
import InfoCollapse from '../common/InfoCollapse.jsx'
|
||
import loglevel from 'loglevel'
|
||
import config from '../../../config'
|
||
const logger = loglevel.getLogger('ApiContextDebug')
|
||
logger.setLevel(config.logLevel)
|
||
|
||
const { Text, Paragraph } = Typography
|
||
|
||
const ApiContextDebug = () => {
|
||
const {
|
||
apiServer,
|
||
error,
|
||
connecting,
|
||
connected,
|
||
fetchLoading,
|
||
lockObject,
|
||
unlockObject,
|
||
fetchObjectLock,
|
||
updateObject,
|
||
createObject,
|
||
deleteObject,
|
||
subscribeToObjectUpdates,
|
||
subscribeToObjectEvent,
|
||
subscribeToObjectTypeUpdates,
|
||
subscribeToObjectLock,
|
||
fetchObject,
|
||
fetchObjects,
|
||
fetchObjectsByProperty,
|
||
fetchSpotlightData,
|
||
fetchFileContent,
|
||
fetchTemplatePreview,
|
||
fetchNotes,
|
||
fetchHostOTP,
|
||
sendObjectAction
|
||
} = useContext(ApiServerContext)
|
||
|
||
const [msgApi, contextHolder] = message.useMessage()
|
||
const [connectionStatus, setConnectionStatus] = useState('disconnected')
|
||
const [socketId, setSocketId] = useState(null)
|
||
|
||
// Test input states
|
||
const [testInputs, setTestInputs] = useState({
|
||
objectId: 'test-id',
|
||
objectType: 'user',
|
||
hostId: 'test-host-id',
|
||
parentId: 'test-parent-id',
|
||
fileName: 'test.gcode',
|
||
query: 'test query',
|
||
action: 'start',
|
||
eventType: 'status',
|
||
properties: ['name', 'email'],
|
||
filter: { active: true },
|
||
scale: 1.0,
|
||
templateContent: 'Test template content',
|
||
testObject: { name: 'Test Object' }
|
||
})
|
||
|
||
// Collapse states
|
||
const [collapseStates, setCollapseStates] = useState({
|
||
fetchTests: false,
|
||
crudTests: false,
|
||
subscriptionTests: false,
|
||
specialTests: false
|
||
})
|
||
|
||
useEffect(() => {
|
||
if (apiServer) {
|
||
setConnectionStatus(apiServer.connected ? 'connected' : 'disconnected')
|
||
setSocketId(apiServer.id)
|
||
|
||
// Listen for connection status changes
|
||
const handleConnect = () => {
|
||
setConnectionStatus('connected')
|
||
setSocketId(apiServer.id)
|
||
}
|
||
|
||
const handleDisconnect = () => {
|
||
setConnectionStatus('disconnected')
|
||
setSocketId(null)
|
||
}
|
||
|
||
apiServer.on('connect', handleConnect)
|
||
apiServer.on('disconnect', handleDisconnect)
|
||
|
||
return () => {
|
||
apiServer.off('connect', handleConnect)
|
||
apiServer.off('disconnect', handleDisconnect)
|
||
}
|
||
} else {
|
||
setConnectionStatus('disconnected')
|
||
setSocketId(null)
|
||
}
|
||
}, [apiServer])
|
||
|
||
// Helper functions
|
||
const updateTestInput = (key, value) => {
|
||
setTestInputs((prev) => ({ ...prev, [key]: value }))
|
||
}
|
||
|
||
const toggleCollapse = (key) => {
|
||
setCollapseStates((prev) => ({ ...prev, [key]: !prev[key] }))
|
||
}
|
||
|
||
const handleReconnect = () => {
|
||
if (apiServer) {
|
||
apiServer.connect()
|
||
msgApi.info('Attempting to reconnect...')
|
||
} else {
|
||
msgApi.warning('No API server instance available')
|
||
}
|
||
}
|
||
|
||
const handleDisconnect = () => {
|
||
if (apiServer) {
|
||
apiServer.disconnect()
|
||
msgApi.info('Disconnected from API server')
|
||
}
|
||
}
|
||
|
||
const testFetchObject = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchObject...', 0)
|
||
const result = await fetchObject(
|
||
testInputs.objectId,
|
||
testInputs.objectType
|
||
)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchObject test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchObject test failed')
|
||
logger.error('fetchObject error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchObjects = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchObjects...', 0)
|
||
const result = await fetchObjects(testInputs.objectType, {
|
||
page: 1,
|
||
limit: 5
|
||
})
|
||
msgApi.destroy()
|
||
msgApi.success('fetchObjects test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchObjects test failed')
|
||
logger.error('fetchObjects error:', err)
|
||
}
|
||
}
|
||
|
||
const testLockObject = () => {
|
||
try {
|
||
lockObject(testInputs.objectId, testInputs.objectType)
|
||
msgApi.success('Lock command sent')
|
||
} catch (err) {
|
||
msgApi.error('Lock command failed')
|
||
logger.error('Lock error:', err)
|
||
}
|
||
}
|
||
|
||
const testUnlockObject = () => {
|
||
try {
|
||
unlockObject(testInputs.objectId, testInputs.objectType)
|
||
msgApi.success('Unlock command sent')
|
||
} catch (err) {
|
||
msgApi.error('Unlock command failed')
|
||
logger.error('Unlock error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchObjectLock = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchObjectLock...', 0)
|
||
const result = await fetchObjectLock(
|
||
testInputs.objectId,
|
||
testInputs.objectType
|
||
)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchObjectLock test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchObjectLock test failed')
|
||
logger.error('fetchObjectLock error:', err)
|
||
}
|
||
}
|
||
|
||
const testUpdateObject = async () => {
|
||
try {
|
||
msgApi.loading('Testing updateObject...', 0)
|
||
const testData = {
|
||
name: 'Test Update',
|
||
updated: new Date().toISOString()
|
||
}
|
||
const result = await updateObject(
|
||
testInputs.objectId,
|
||
testInputs.objectType,
|
||
testData
|
||
)
|
||
msgApi.destroy()
|
||
msgApi.success('updateObject test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('updateObject test failed')
|
||
logger.error('updateObject error:', err)
|
||
}
|
||
}
|
||
|
||
const testCreateObject = async () => {
|
||
try {
|
||
msgApi.loading('Testing createObject...', 0)
|
||
const testData = {
|
||
name: 'Test Create',
|
||
created: new Date().toISOString()
|
||
}
|
||
const result = await createObject(testInputs.objectType, testData)
|
||
msgApi.destroy()
|
||
msgApi.success('createObject test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('createObject test failed')
|
||
logger.error('createObject error:', err)
|
||
}
|
||
}
|
||
|
||
const testDeleteObject = async () => {
|
||
try {
|
||
msgApi.loading('Testing deleteObject...', 0)
|
||
const result = await deleteObject(
|
||
testInputs.objectId,
|
||
testInputs.objectType
|
||
)
|
||
msgApi.destroy()
|
||
msgApi.success('deleteObject test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('deleteObject test failed')
|
||
logger.error('deleteObject error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchObjectsByProperty = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchObjectsByProperty...', 0)
|
||
const params = {
|
||
properties: testInputs.properties,
|
||
filter: testInputs.filter,
|
||
masterFilter: {}
|
||
}
|
||
const result = await fetchObjectsByProperty(testInputs.objectType, params)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchObjectsByProperty test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchObjectsByProperty test failed')
|
||
logger.error('fetchObjectsByProperty error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchSpotlightData = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchSpotlightData...', 0)
|
||
const result = await fetchSpotlightData(testInputs.query)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchSpotlightData test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchSpotlightData test failed')
|
||
logger.error('fetchSpotlightData error:', err)
|
||
}
|
||
}
|
||
|
||
const testfetchFileContent = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchFileContent...', 0)
|
||
await fetchFileContent(
|
||
testInputs.objectId,
|
||
'gcodefile',
|
||
testInputs.fileName
|
||
)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchFileContent test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchFileContent test failed')
|
||
logger.error('fetchFileContent error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchTemplatePreview = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchTemplatePreview...', 0)
|
||
|
||
fetchTemplatePreview(
|
||
testInputs.objectId,
|
||
testInputs.templateContent,
|
||
testInputs.testObject,
|
||
testInputs.scale,
|
||
(result) => {
|
||
msgApi.destroy()
|
||
if (result.success) {
|
||
msgApi.success('fetchTemplatePreview test completed')
|
||
} else {
|
||
msgApi.error('fetchTemplatePreview test failed')
|
||
}
|
||
}
|
||
)
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchTemplatePreview test failed')
|
||
logger.error('fetchTemplatePreview error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchNotes = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchNotes...', 0)
|
||
const result = await fetchNotes(testInputs.parentId)
|
||
msgApi.destroy()
|
||
msgApi.success('fetchNotes test completed')
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchNotes test failed')
|
||
logger.error('fetchNotes error:', err)
|
||
}
|
||
}
|
||
|
||
const testFetchHostOTP = async () => {
|
||
try {
|
||
msgApi.loading('Testing fetchHostOTP...', 0)
|
||
|
||
fetchHostOTP(testInputs.hostId, (result) => {
|
||
msgApi.destroy()
|
||
if (result.otp) {
|
||
msgApi.success('fetchHostOTP test completed: ' + result.otp)
|
||
} else {
|
||
msgApi.error('fetchHostOTP test failed')
|
||
}
|
||
})
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('fetchHostOTP test failed')
|
||
logger.error('fetchHostOTP error:', err)
|
||
}
|
||
}
|
||
|
||
const testSendObjectAction = async () => {
|
||
try {
|
||
msgApi.loading('Testing sendObjectAction...', 0)
|
||
|
||
sendObjectAction(
|
||
testInputs.objectId,
|
||
'printer',
|
||
testInputs.action,
|
||
(result) => {
|
||
msgApi.destroy()
|
||
if (result.success) {
|
||
msgApi.success('sendObjectAction test completed')
|
||
} else {
|
||
msgApi.error('sendObjectAction test failed')
|
||
}
|
||
}
|
||
)
|
||
} catch (err) {
|
||
msgApi.destroy()
|
||
msgApi.error('sendObjectAction test failed')
|
||
logger.error('sendObjectAction error:', err)
|
||
}
|
||
}
|
||
|
||
const testSubscribeToObjectUpdates = () => {
|
||
try {
|
||
const callback = (data) => {
|
||
logger.debug('Object update received:', data)
|
||
}
|
||
const unsubscribe = subscribeToObjectUpdates(
|
||
testInputs.objectId,
|
||
testInputs.objectType,
|
||
callback
|
||
)
|
||
msgApi.success('Subscribed to object updates')
|
||
logger.debug('Subscribed to object updates for test-id')
|
||
|
||
// Store unsubscribe function for cleanup
|
||
setTimeout(() => {
|
||
if (unsubscribe) {
|
||
unsubscribe()
|
||
logger.debug('Unsubscribed from object updates')
|
||
}
|
||
}, 10000) // Auto-unsubscribe after 10 seconds
|
||
} catch (err) {
|
||
msgApi.error('Subscribe to object updates failed')
|
||
logger.error('Subscribe error:', err)
|
||
}
|
||
}
|
||
|
||
const testSubscribeToObjectEvent = () => {
|
||
try {
|
||
const callback = (event) => {
|
||
logger.debug('Object event received:', event)
|
||
}
|
||
const unsubscribe = subscribeToObjectEvent(
|
||
testInputs.objectId,
|
||
'printer',
|
||
testInputs.eventType,
|
||
callback
|
||
)
|
||
msgApi.success('Subscribed to object events')
|
||
logger.debug('Subscribed to object events for test-id')
|
||
|
||
// Store unsubscribe function for cleanup
|
||
setTimeout(() => {
|
||
if (unsubscribe) {
|
||
unsubscribe()
|
||
logger.debug('Unsubscribed from object events')
|
||
}
|
||
}, 10000) // Auto-unsubscribe after 10 seconds
|
||
} catch (err) {
|
||
msgApi.error('Subscribe to object events failed')
|
||
logger.error('Subscribe error:', err)
|
||
}
|
||
}
|
||
|
||
const testSubscribeToObjectTypeUpdates = () => {
|
||
try {
|
||
const callback = (data) => {
|
||
logger.debug('Object type update received:', data)
|
||
}
|
||
const unsubscribe = subscribeToObjectTypeUpdates(
|
||
testInputs.objectType,
|
||
callback
|
||
)
|
||
msgApi.success('Subscribed to object type updates')
|
||
logger.debug('Subscribed to object type updates for user')
|
||
|
||
// Store unsubscribe function for cleanup
|
||
setTimeout(() => {
|
||
if (unsubscribe) {
|
||
unsubscribe()
|
||
logger.debug('Unsubscribed from object type updates')
|
||
}
|
||
}, 10000) // Auto-unsubscribe after 10 seconds
|
||
} catch (err) {
|
||
msgApi.error('Subscribe to object type updates failed')
|
||
logger.error('Subscribe error:', err)
|
||
}
|
||
}
|
||
|
||
const testSubscribeToObjectLock = () => {
|
||
try {
|
||
const callback = (lockData) => {
|
||
logger.debug('Object lock update received:', lockData)
|
||
}
|
||
const unsubscribe = subscribeToObjectLock(
|
||
testInputs.objectId,
|
||
testInputs.objectType,
|
||
callback
|
||
)
|
||
msgApi.success('Subscribed to object lock updates')
|
||
logger.debug('Subscribed to object lock updates for test-id')
|
||
|
||
// Store unsubscribe function for cleanup
|
||
setTimeout(() => {
|
||
if (unsubscribe) {
|
||
unsubscribe()
|
||
logger.debug('Unsubscribed from object lock updates')
|
||
}
|
||
}, 10000) // Auto-unsubscribe after 10 seconds
|
||
} catch (err) {
|
||
msgApi.error('Subscribe to object lock updates failed')
|
||
logger.error('Subscribe error:', err)
|
||
}
|
||
}
|
||
|
||
const actionItems = {
|
||
items: [
|
||
{
|
||
label: 'Reconnect',
|
||
key: 'reconnect',
|
||
disabled: connected
|
||
},
|
||
{
|
||
label: 'Disconnect',
|
||
key: 'disconnect',
|
||
disabled: !connected
|
||
},
|
||
{
|
||
type: 'divider'
|
||
},
|
||
{
|
||
label: 'Reload',
|
||
key: 'reload',
|
||
icon: <ReloadIcon />
|
||
}
|
||
],
|
||
onClick: ({ key }) => {
|
||
switch (key) {
|
||
case 'reconnect':
|
||
handleReconnect()
|
||
break
|
||
case 'disconnect':
|
||
handleDisconnect()
|
||
break
|
||
case 'reload':
|
||
msgApi.info('Reloading API State...')
|
||
window.location.reload()
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
const getConnectionStatusColor = () => {
|
||
switch (connectionStatus) {
|
||
case 'connected':
|
||
return 'success'
|
||
case 'connecting':
|
||
return 'processing'
|
||
case 'disconnected':
|
||
return 'error'
|
||
default:
|
||
return 'default'
|
||
}
|
||
}
|
||
|
||
return (
|
||
<Flex vertical gap='large' style={{ height: '100%', minHeight: 0 }}>
|
||
{contextHolder}
|
||
|
||
{/* Header with Actions */}
|
||
<Flex justify={'space-between'} align={'center'}>
|
||
<Space>
|
||
<Dropdown menu={actionItems}>
|
||
<Button>Actions</Button>
|
||
</Dropdown>
|
||
</Space>
|
||
</Flex>
|
||
|
||
<Descriptions bordered>
|
||
<Descriptions.Item label='Status'>
|
||
<Space>
|
||
<Tag color={getConnectionStatusColor()} icon={<CloudIcon />}>
|
||
{connectionStatus.charAt(0).toUpperCase() +
|
||
connectionStatus.slice(1)}
|
||
</Tag>
|
||
</Space>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Connecting'>
|
||
<BoolDisplay value={connecting} />
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Connected'>
|
||
<BoolDisplay value={connected} />
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Socket ID'>
|
||
<Text code>{socketId || 'None'}</Text>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Fetch Loading'>
|
||
<BoolDisplay value={fetchLoading} />
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Error'>
|
||
<Text type={error ? 'danger' : 'secondary'}>{error || 'None'}</Text>
|
||
</Descriptions.Item>
|
||
</Descriptions>
|
||
|
||
<InfoCollapse
|
||
title='Params'
|
||
icon={<span>🔎</span>}
|
||
active={collapseStates.params}
|
||
onToggle={() => toggleCollapse('params')}
|
||
collapseKey='params'
|
||
>
|
||
<Descriptions bordered column={2}>
|
||
<Descriptions.Item label='Object ID'>
|
||
<Input
|
||
value={testInputs.objectId}
|
||
onChange={(e) => updateTestInput('objectId', e.target.value)}
|
||
placeholder='Enter object ID'
|
||
size='small'
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Object Type'>
|
||
<Select
|
||
value={testInputs.objectType}
|
||
onChange={(value) => updateTestInput('objectType', value)}
|
||
style={{ width: '100%' }}
|
||
options={[
|
||
{ value: 'user', label: 'User' },
|
||
{ value: 'printer', label: 'Printer' },
|
||
{ value: 'job', label: 'Job' },
|
||
{ value: 'filament', label: 'Filament' },
|
||
{ value: 'gcodefile', label: 'GCode File' }
|
||
]}
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Host ID'>
|
||
<Input
|
||
value={testInputs.hostId}
|
||
onChange={(e) => updateTestInput('hostId', e.target.value)}
|
||
placeholder='Enter host ID'
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Parent ID'>
|
||
<Input
|
||
value={testInputs.parentId}
|
||
onChange={(e) => updateTestInput('parentId', e.target.value)}
|
||
placeholder='Enter parent ID'
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='File Name'>
|
||
<Input
|
||
value={testInputs.fileName}
|
||
onChange={(e) => updateTestInput('fileName', e.target.value)}
|
||
placeholder='Enter file name'
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Query'>
|
||
<Input
|
||
value={testInputs.query}
|
||
onChange={(e) => updateTestInput('query', e.target.value)}
|
||
placeholder='Enter search query'
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Action'>
|
||
<Select
|
||
value={testInputs.action}
|
||
onChange={(value) => updateTestInput('action', value)}
|
||
style={{ width: '100%' }}
|
||
options={[
|
||
{ value: 'start', label: 'Start' },
|
||
{ value: 'stop', label: 'Stop' },
|
||
{ value: 'pause', label: 'Pause' },
|
||
{ value: 'resume', label: 'Resume' }
|
||
]}
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Event Type'>
|
||
<Select
|
||
value={testInputs.eventType}
|
||
onChange={(value) => updateTestInput('eventType', value)}
|
||
style={{ width: '100%' }}
|
||
options={[
|
||
{ value: 'status', label: 'Status' },
|
||
{ value: 'progress', label: 'Progress' },
|
||
{ value: 'error', label: 'Error' },
|
||
{ value: 'complete', label: 'Complete' }
|
||
]}
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Scale'>
|
||
<InputNumber
|
||
value={testInputs.scale}
|
||
onChange={(value) => updateTestInput('scale', value)}
|
||
min={0.1}
|
||
max={10}
|
||
step={0.1}
|
||
style={{ width: '100%' }}
|
||
/>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label='Template Content' span={1}>
|
||
<Input.TextArea
|
||
value={testInputs.templateContent}
|
||
onChange={(e) =>
|
||
updateTestInput('templateContent', e.target.value)
|
||
}
|
||
placeholder='Enter template content'
|
||
rows={2}
|
||
/>
|
||
</Descriptions.Item>
|
||
</Descriptions>
|
||
</InfoCollapse>
|
||
|
||
{/* Test Sections */}
|
||
<div style={{ height: '100%', overflow: 'auto' }}>
|
||
<Flex vertical gap={'large'}>
|
||
{/* Fetch Tests */}
|
||
<InfoCollapse
|
||
title='Fetch Tests'
|
||
icon={<span>📥</span>}
|
||
active={collapseStates.fetchTests}
|
||
onToggle={() => toggleCollapse('fetchTests')}
|
||
collapseKey='fetchTests'
|
||
>
|
||
<Space direction='vertical' style={{ width: '100%' }}>
|
||
<Button onClick={testFetchObject} block>
|
||
Test fetchObject
|
||
</Button>
|
||
<Button onClick={testFetchObjects} block>
|
||
Test fetchObjects
|
||
</Button>
|
||
<Button onClick={testFetchObjectLock} block>
|
||
Test fetchObjectLock
|
||
</Button>
|
||
<Button onClick={testFetchObjectsByProperty} block>
|
||
Test fetchObjectsByProperty
|
||
</Button>
|
||
<Button onClick={testFetchSpotlightData} block>
|
||
Test fetchSpotlightData
|
||
</Button>
|
||
<Button onClick={testfetchFileContent} block>
|
||
Test fetchFileContent
|
||
</Button>
|
||
<Button onClick={testFetchNotes} block>
|
||
Test fetchNotes
|
||
</Button>
|
||
</Space>
|
||
</InfoCollapse>
|
||
|
||
{/* CRUD Tests */}
|
||
<InfoCollapse
|
||
title='CRUD Tests'
|
||
icon={<span>✏️</span>}
|
||
active={collapseStates.crudTests}
|
||
onToggle={() => toggleCollapse('crudTests')}
|
||
collapseKey='crudTests'
|
||
>
|
||
<Space direction='vertical' style={{ width: '100%' }}>
|
||
<Button onClick={testLockObject} block>
|
||
Test Lock Object
|
||
</Button>
|
||
<Button onClick={testUnlockObject} block>
|
||
Test Unlock Object
|
||
</Button>
|
||
<Button onClick={testUpdateObject} block>
|
||
Test updateObject
|
||
</Button>
|
||
<Button onClick={testCreateObject} block>
|
||
Test createObject
|
||
</Button>
|
||
<Button onClick={testDeleteObject} block>
|
||
Test deleteObject
|
||
</Button>
|
||
</Space>
|
||
</InfoCollapse>
|
||
|
||
{/* Special Tests */}
|
||
<InfoCollapse
|
||
title='Special Tests'
|
||
icon={<span>🔧</span>}
|
||
active={collapseStates.specialTests}
|
||
onToggle={() => toggleCollapse('specialTests')}
|
||
collapseKey='specialTests'
|
||
>
|
||
<Space direction='vertical' style={{ width: '100%' }}>
|
||
<Button onClick={testFetchTemplatePreview} block>
|
||
Test fetchTemplatePreview
|
||
</Button>
|
||
<Button onClick={testFetchHostOTP} block>
|
||
Test fetchHostOTP
|
||
</Button>
|
||
<Button onClick={testSendObjectAction} block>
|
||
Test sendObjectAction
|
||
</Button>
|
||
</Space>
|
||
</InfoCollapse>
|
||
|
||
{/* Subscription Tests */}
|
||
<InfoCollapse
|
||
title='Subscription Tests'
|
||
icon={<span>📡</span>}
|
||
active={collapseStates.subscriptionTests}
|
||
onToggle={() => toggleCollapse('subscriptionTests')}
|
||
collapseKey='subscriptionTests'
|
||
>
|
||
<Space direction='vertical' style={{ width: '100%' }}>
|
||
<Button onClick={testSubscribeToObjectUpdates} block>
|
||
Test Subscribe Object Updates
|
||
</Button>
|
||
<Button onClick={testSubscribeToObjectEvent} block>
|
||
Test Subscribe Object Events
|
||
</Button>
|
||
<Button onClick={testSubscribeToObjectTypeUpdates} block>
|
||
Test Subscribe Object Type Updates
|
||
</Button>
|
||
<Button onClick={testSubscribeToObjectLock} block>
|
||
Test Subscribe Object Lock
|
||
</Button>
|
||
</Space>
|
||
</InfoCollapse>
|
||
|
||
{/* API Server Instance Info */}
|
||
<InfoCollapse
|
||
title='API Server Instance'
|
||
icon={<span>🖥️</span>}
|
||
active={false}
|
||
onToggle={() => {}}
|
||
collapseKey='apiServer'
|
||
>
|
||
<pre style={{ margin: 0, fontSize: 12 }}>
|
||
{apiServer ? (
|
||
<Paragraph>
|
||
<pre>
|
||
{JSON.stringify(
|
||
{
|
||
connected: apiServer.connected,
|
||
id: apiServer.id,
|
||
transport: apiServer.io.engine.transport.name,
|
||
readyState: apiServer.io.engine.readyState
|
||
},
|
||
null,
|
||
2
|
||
)}
|
||
</pre>
|
||
</Paragraph>
|
||
) : (
|
||
<Text type='secondary'>No API server instance</Text>
|
||
)}
|
||
</pre>
|
||
</InfoCollapse>
|
||
</Flex>
|
||
</div>
|
||
</Flex>
|
||
)
|
||
}
|
||
|
||
export default ApiContextDebug
|