@rozenite/vite-plugin 1.13.0 → 2.1.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 +12 -0
- package/dist/bundle-dts.d.ts.map +1 -1
- package/dist/client-plugin.d.ts.map +1 -1
- package/dist/dev-host/assets/index-BgAxGQdD.js +13 -0
- package/dist/dev-host/assets/index-ClIYIppU.css +1 -0
- package/dist/dev-host/index.html +3 -3
- package/dist/dev-host/manifest.json +2 -2
- package/dist/index.cjs +34 -63
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -63
- package/dist/load-config.d.ts.map +1 -1
- package/dist/package-json.d.ts.map +1 -1
- package/dist/react-native-plugin.d.ts.map +1 -1
- package/dist/require-plugin.d.ts.map +1 -1
- package/dist/sdk-plugin.d.ts.map +1 -1
- package/dist/server-plugin.d.ts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +29 -30
- package/src/bundle-dts.ts +6 -14
- package/src/client-plugin.ts +13 -36
- package/src/dev-host/App.tsx +184 -414
- package/src/dev-host/components/DispatchForm.tsx +97 -121
- package/src/dev-host/components/FlowList.tsx +70 -102
- package/src/dev-host/components/MessageDetailsPane.tsx +50 -83
- package/src/dev-host/components/MessageLogPane.tsx +75 -66
- package/src/dev-host/components/PanelTabs.tsx +19 -10
- package/src/dev-host/constants.ts +0 -19
- package/src/dev-host/flow-runtime.ts +15 -12
- package/src/dev-host/index.html +1 -1
- package/src/dev-host/main.tsx +1 -10
- package/src/dev-host/styles.css +162 -830
- package/src/dev-host/types.ts +0 -9
- package/src/dev-host/utils.ts +1 -7
- package/src/dev-host/vite.config.mts +2 -0
- package/src/index.ts +16 -16
- package/src/load-config.ts +9 -20
- package/src/package-json.ts +1 -3
- package/src/react-native-plugin.ts +4 -2
- package/src/require-plugin.ts +6 -18
- package/src/sdk-plugin.ts +3 -0
- package/src/server-plugin.ts +3 -0
- package/src/utils.ts +1 -4
- package/dist/dev-host/assets/index-CkxvBMpp.css +0 -1
- package/dist/dev-host/assets/index-cNKHRwej.js +0 -11
- package/src/dev-host/components/MessagePayloadDetail.tsx +0 -32
- package/src/dev-host/components/ResizeHandle.tsx +0 -33
- package/src/dev-host/components/icons.tsx +0 -79
- package/src/dev-host/components/ui/Button.tsx +0 -91
- package/src/dev-host/components/ui/DropdownMenu.tsx +0 -84
- package/src/dev-host/components/ui/IconButton.tsx +0 -41
- package/src/dev-host/components/ui/Input.tsx +0 -73
- package/src/dev-host/components/ui/ScrollArea.tsx +0 -20
- package/src/dev-host/components/ui/Tabs.tsx +0 -166
- package/src/dev-host/components/ui/Textarea.tsx +0 -79
- package/src/dev-host/components/ui/ToggleGroup.tsx +0 -120
|
@@ -1,13 +1,8 @@
|
|
|
1
|
+
import { Button, Input, Select, Tabs, Textarea } from '@rozenite/ui';
|
|
2
|
+
import { RotateCcw, Send } from 'lucide-react';
|
|
1
3
|
import { useState, type FormEvent } from 'react';
|
|
2
4
|
import type { DevHostFlowEntry, DevHostFlowRunState, DevHostPresetEntry } from '../types.js';
|
|
3
|
-
import { ClearIcon, PresetsIcon, SendIcon } from './icons.js';
|
|
4
5
|
import { FlowList } from './FlowList.js';
|
|
5
|
-
import { DropdownMenu, type DropdownMenuItem } from './ui/DropdownMenu.js';
|
|
6
|
-
import { IconButton } from './ui/IconButton.js';
|
|
7
|
-
import { Input } from './ui/Input.js';
|
|
8
|
-
import { ScrollArea } from './ui/ScrollArea.js';
|
|
9
|
-
import { Textarea } from './ui/Textarea.js';
|
|
10
|
-
import { ToggleGroup } from './ui/ToggleGroup.js';
|
|
11
6
|
|
|
12
7
|
type DispatchFormProps = {
|
|
13
8
|
commandType: string;
|
|
@@ -43,127 +38,108 @@ export const DispatchForm = ({
|
|
|
43
38
|
onSubmit,
|
|
44
39
|
}: DispatchFormProps) => {
|
|
45
40
|
const [activeTab, setActiveTab] = useState<'dispatch' | 'flows'>('dispatch');
|
|
46
|
-
const presetItems: DropdownMenuItem<DevHostPresetEntry>[] = presets.map((preset) => ({
|
|
47
|
-
id: preset.displayName,
|
|
48
|
-
label: preset.displayName,
|
|
49
|
-
item: preset,
|
|
50
|
-
}));
|
|
51
|
-
const presetButton = (
|
|
52
|
-
<IconButton
|
|
53
|
-
type="button"
|
|
54
|
-
variant="default"
|
|
55
|
-
aria-label={presets.length > 0 ? 'Open presets' : 'No presets available'}
|
|
56
|
-
title={presets.length > 0 ? 'Presets' : 'No presets available'}
|
|
57
|
-
disabled={presets.length === 0}
|
|
58
|
-
overrides={{
|
|
59
|
-
BaseButton: {
|
|
60
|
-
style: {
|
|
61
|
-
borderRadius: '6px',
|
|
62
|
-
backgroundColor: 'rgba(255, 255, 255, 0.04)',
|
|
63
|
-
color: 'rgba(255, 255, 255, 0.88)',
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
<PresetsIcon />
|
|
69
|
-
</IconButton>
|
|
70
|
-
);
|
|
71
41
|
|
|
72
42
|
return (
|
|
73
|
-
<
|
|
74
|
-
<
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
</div>
|
|
43
|
+
<section className="dev-host-pane">
|
|
44
|
+
<header className="dev-host-pane-header">
|
|
45
|
+
<h2 className="dev-host-pane-title">Actions</h2>
|
|
46
|
+
</header>
|
|
78
47
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
]}
|
|
90
|
-
/>
|
|
91
|
-
|
|
92
|
-
{activeTab === 'dispatch'
|
|
93
|
-
? presets.length > 0
|
|
94
|
-
? <DropdownMenu items={presetItems} onSelect={onApplyPreset}>{presetButton}</DropdownMenu>
|
|
95
|
-
: presetButton
|
|
96
|
-
: null}
|
|
97
|
-
</div>
|
|
48
|
+
<Tabs
|
|
49
|
+
className="flex min-h-0 flex-1 flex-col"
|
|
50
|
+
value={activeTab}
|
|
51
|
+
onValueChange={(value) => setActiveTab(value as 'dispatch' | 'flows')}
|
|
52
|
+
>
|
|
53
|
+
<div className="dev-host-tabs-header">
|
|
54
|
+
<Tabs.List aria-label="Action modes">
|
|
55
|
+
<Tabs.Tab value="dispatch">Dispatch</Tabs.Tab>
|
|
56
|
+
<Tabs.Tab value="flows">Flows</Tabs.Tab>
|
|
57
|
+
</Tabs.List>
|
|
98
58
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
59
|
+
{activeTab === 'dispatch' ? (
|
|
60
|
+
<Select
|
|
61
|
+
value={null}
|
|
62
|
+
onValueChange={(value) => {
|
|
63
|
+
const preset = presets.find((item) => item.name === value);
|
|
64
|
+
if (preset) {
|
|
65
|
+
onApplyPreset(preset);
|
|
66
|
+
}
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<Select.Trigger
|
|
70
|
+
className="w-auto"
|
|
71
|
+
aria-label={presets.length > 0 ? 'Open presets' : 'No presets available'}
|
|
72
|
+
disabled={presets.length === 0}
|
|
73
|
+
title={presets.length > 0 ? 'Presets' : 'No presets available'}
|
|
74
|
+
>
|
|
75
|
+
<Select.Value>Presets</Select.Value>
|
|
76
|
+
</Select.Trigger>
|
|
77
|
+
<Select.Content align="end">
|
|
78
|
+
{presets.map((preset) => (
|
|
79
|
+
<Select.Item key={preset.name} value={preset.name}>
|
|
80
|
+
{preset.displayName}
|
|
81
|
+
</Select.Item>
|
|
82
|
+
))}
|
|
83
|
+
</Select.Content>
|
|
84
|
+
</Select>
|
|
85
|
+
) : null}
|
|
86
|
+
</div>
|
|
114
87
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
</div>
|
|
88
|
+
<Tabs.Panel value="dispatch" className="dev-host-tab-panel">
|
|
89
|
+
<form className="dev-host-form" onSubmit={onSubmit}>
|
|
90
|
+
<label className="dev-host-field">
|
|
91
|
+
<span className="dev-host-label">Command</span>
|
|
92
|
+
<Input
|
|
93
|
+
value={commandType}
|
|
94
|
+
onChange={(event) => onCommandTypeChange(event.currentTarget.value)}
|
|
95
|
+
placeholder="get-snapshot"
|
|
96
|
+
spellCheck={false}
|
|
97
|
+
/>
|
|
98
|
+
</label>
|
|
127
99
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</IconButton>
|
|
100
|
+
<label className="dev-host-field">
|
|
101
|
+
<span className="dev-host-label">Payload</span>
|
|
102
|
+
<Textarea
|
|
103
|
+
value={commandPayload}
|
|
104
|
+
onChange={(event) => onCommandPayloadChange(event.currentTarget.value)}
|
|
105
|
+
placeholder='{"example": true}'
|
|
106
|
+
spellCheck={false}
|
|
107
|
+
/>
|
|
108
|
+
</label>
|
|
138
109
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
110
|
+
<div className="dev-host-actions">
|
|
111
|
+
<Button
|
|
112
|
+
variant="outline"
|
|
113
|
+
size="icon"
|
|
114
|
+
onClick={onReset}
|
|
115
|
+
aria-label="Reset dispatcher"
|
|
116
|
+
title="Reset dispatcher"
|
|
117
|
+
>
|
|
118
|
+
<RotateCcw />
|
|
119
|
+
</Button>
|
|
120
|
+
<Button
|
|
121
|
+
type="submit"
|
|
122
|
+
size="icon"
|
|
123
|
+
disabled={!canDispatch}
|
|
124
|
+
aria-label="Dispatch message"
|
|
125
|
+
title="Dispatch message"
|
|
126
|
+
>
|
|
127
|
+
<Send />
|
|
128
|
+
</Button>
|
|
129
|
+
</div>
|
|
130
|
+
</form>
|
|
131
|
+
</Tabs.Panel>
|
|
152
132
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
</div>
|
|
165
|
-
</ScrollArea>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
133
|
+
<Tabs.Panel value="flows" className="dev-host-tab-panel">
|
|
134
|
+
<FlowList
|
|
135
|
+
flows={flows}
|
|
136
|
+
flowRuns={flowRuns}
|
|
137
|
+
hasRunningFlow={hasRunningFlow}
|
|
138
|
+
onRunFlow={onRunFlow}
|
|
139
|
+
onStopFlow={onStopFlow}
|
|
140
|
+
/>
|
|
141
|
+
</Tabs.Panel>
|
|
142
|
+
</Tabs>
|
|
143
|
+
</section>
|
|
168
144
|
);
|
|
169
145
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { Badge, Button, EmptyState } from '@rozenite/ui';
|
|
2
|
+
import { Play, Square } from 'lucide-react';
|
|
1
3
|
import { formatPayloadForCommandInput } from '../utils.js';
|
|
2
4
|
import type { DevHostFlowEntry, DevHostFlowRunState } from '../types.js';
|
|
3
|
-
import { Button } from './ui/Button.js';
|
|
4
5
|
|
|
5
6
|
type FlowListProps = {
|
|
6
7
|
flows: DevHostFlowEntry[];
|
|
@@ -11,129 +12,96 @@ type FlowListProps = {
|
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
const getStatusLabel = (status: DevHostFlowRunState['status']) => {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
switch (status) {
|
|
16
|
+
case 'running':
|
|
17
|
+
return 'Running';
|
|
18
|
+
case 'succeeded':
|
|
19
|
+
return 'Completed';
|
|
20
|
+
case 'failed':
|
|
21
|
+
return 'Failed';
|
|
22
|
+
case 'aborted':
|
|
23
|
+
return 'Stopped';
|
|
16
24
|
}
|
|
17
|
-
|
|
18
|
-
if (status === 'succeeded') {
|
|
19
|
-
return 'Completed';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (status === 'failed') {
|
|
23
|
-
return 'Failed';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (status === 'aborted') {
|
|
27
|
-
return 'Stopped';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return status;
|
|
31
25
|
};
|
|
32
26
|
|
|
33
|
-
export const FlowList = ({
|
|
27
|
+
export const FlowList = ({
|
|
28
|
+
flows,
|
|
29
|
+
flowRuns,
|
|
30
|
+
hasRunningFlow,
|
|
31
|
+
onRunFlow,
|
|
32
|
+
onStopFlow,
|
|
33
|
+
}: FlowListProps) => {
|
|
34
34
|
if (flows.length === 0) {
|
|
35
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
<EmptyState
|
|
37
|
+
className="h-full"
|
|
38
|
+
title="No flows configured"
|
|
39
|
+
description="Add flows to rozenite.config.ts to run them here."
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
const hasExecutionState = flowRuns.length > 0;
|
|
39
|
-
|
|
40
44
|
return (
|
|
41
|
-
<div className="
|
|
42
|
-
<div className="
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const isActive = hasRunningFlow(flow.name);
|
|
45
|
+
<div className="dev-host-flow-list">
|
|
46
|
+
<div className="dev-host-field">
|
|
47
|
+
<span className="dev-host-label">Available flows</span>
|
|
48
|
+
<div className="grid gap-2">
|
|
49
|
+
{flows.map((flow) => {
|
|
50
|
+
const isRunning = hasRunningFlow(flow.name);
|
|
48
51
|
|
|
49
52
|
return (
|
|
50
53
|
<Button
|
|
51
|
-
key={
|
|
52
|
-
|
|
54
|
+
key={flow.name}
|
|
55
|
+
variant={isRunning ? 'secondary' : 'outline'}
|
|
56
|
+
className="dev-host-flow-button"
|
|
53
57
|
onClick={() => onRunFlow(flow)}
|
|
54
|
-
|
|
55
|
-
isSelected={isActive}
|
|
56
|
-
title={`Run ${flow.displayName}`}
|
|
57
|
-
overrides={{
|
|
58
|
-
BaseButton: {
|
|
59
|
-
style: {
|
|
60
|
-
display: 'flex',
|
|
61
|
-
alignItems: 'center',
|
|
62
|
-
justifyContent: 'space-between',
|
|
63
|
-
gap: '12px',
|
|
64
|
-
width: '100%',
|
|
65
|
-
borderRadius: '8px',
|
|
66
|
-
backgroundColor: isActive ? 'rgba(130, 50, 255, 0.14)' : 'rgba(255, 255, 255, 0.03)',
|
|
67
|
-
borderColor: isActive ? 'rgba(130, 50, 255, 0.45)' : 'rgba(255, 255, 255, 0.08)',
|
|
68
|
-
color: 'rgba(255, 255, 255, 0.88)',
|
|
69
|
-
paddingTop: '10px',
|
|
70
|
-
paddingRight: '12px',
|
|
71
|
-
paddingBottom: '10px',
|
|
72
|
-
paddingLeft: '12px',
|
|
73
|
-
textAlign: 'left',
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
}}
|
|
58
|
+
aria-label={`Run ${flow.displayName}`}
|
|
77
59
|
>
|
|
78
|
-
<span className="
|
|
60
|
+
<span className="dev-host-flow-name">
|
|
61
|
+
<Play />
|
|
79
62
|
{flow.displayName}
|
|
80
|
-
{flow.autoRun ? <
|
|
63
|
+
{flow.autoRun ? <Badge variant="outline">Auto</Badge> : null}
|
|
64
|
+
</span>
|
|
65
|
+
<span className="text-xs text-muted-foreground">
|
|
66
|
+
{isRunning ? 'Running' : 'Run'}
|
|
81
67
|
</span>
|
|
82
|
-
<span className="rz-flow-list-action">{isActive ? 'Running' : 'Run'}</span>
|
|
83
68
|
</Button>
|
|
84
69
|
);
|
|
85
70
|
})}
|
|
86
71
|
</div>
|
|
87
72
|
</div>
|
|
88
73
|
|
|
89
|
-
{
|
|
90
|
-
<div className="
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
{isRunning ? (
|
|
106
|
-
<Button
|
|
107
|
-
type="button"
|
|
108
|
-
variant="pill"
|
|
109
|
-
onClick={() => onStopFlow(flowRun.id)}
|
|
110
|
-
overrides={{
|
|
111
|
-
BaseButton: {
|
|
112
|
-
style: {
|
|
113
|
-
flexShrink: 0,
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
}}
|
|
117
|
-
>
|
|
118
|
-
Stop
|
|
119
|
-
</Button>
|
|
120
|
-
) : null}
|
|
121
|
-
</div>
|
|
122
|
-
|
|
123
|
-
<div className="rz-flow-state-status">{getStatusLabel(flowRun.status)}</div>
|
|
124
|
-
|
|
125
|
-
{flowRun.error ? (
|
|
126
|
-
<div className="rz-flow-state-error">{flowRun.error}</div>
|
|
127
|
-
) : null}
|
|
128
|
-
|
|
129
|
-
{flowRun.result != null ? (
|
|
130
|
-
<pre className="rz-flow-state-result">
|
|
131
|
-
{formatPayloadForCommandInput(flowRun.result)}
|
|
132
|
-
</pre>
|
|
74
|
+
{flowRuns.length > 0 ? (
|
|
75
|
+
<div className="dev-host-field">
|
|
76
|
+
<span className="dev-host-label">Flow runs</span>
|
|
77
|
+
<div className="dev-host-flow-runs">
|
|
78
|
+
{flowRuns.map((flowRun) => (
|
|
79
|
+
<div key={flowRun.id} className="dev-host-flow-state" data-status={flowRun.status}>
|
|
80
|
+
<div className="dev-host-flow-state-header">
|
|
81
|
+
<span className="dev-host-flow-title">
|
|
82
|
+
{flowRun.flowDisplayName}
|
|
83
|
+
{flowRun.autoRun ? <Badge variant="outline">Auto</Badge> : null}
|
|
84
|
+
</span>
|
|
85
|
+
{flowRun.status === 'running' ? (
|
|
86
|
+
<Button variant="ghost" size="compact" onClick={() => onStopFlow(flowRun.id)}>
|
|
87
|
+
<Square />
|
|
88
|
+
Stop
|
|
89
|
+
</Button>
|
|
133
90
|
) : null}
|
|
134
91
|
</div>
|
|
135
|
-
|
|
136
|
-
|
|
92
|
+
<span className="text-xs text-muted-foreground">
|
|
93
|
+
{getStatusLabel(flowRun.status)}
|
|
94
|
+
</span>
|
|
95
|
+
{flowRun.error ? (
|
|
96
|
+
<div className="dev-host-flow-state-error">{flowRun.error}</div>
|
|
97
|
+
) : null}
|
|
98
|
+
{flowRun.result != null ? (
|
|
99
|
+
<pre className="dev-host-flow-state-result">
|
|
100
|
+
{formatPayloadForCommandInput(flowRun.result)}
|
|
101
|
+
</pre>
|
|
102
|
+
) : null}
|
|
103
|
+
</div>
|
|
104
|
+
))}
|
|
137
105
|
</div>
|
|
138
106
|
</div>
|
|
139
107
|
) : null}
|
|
@@ -1,103 +1,70 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { Button, JsonInspector, ScrollArea } from '@rozenite/ui';
|
|
2
|
+
import { Send, X } from 'lucide-react';
|
|
3
|
+
import type { MessageEntry } from '../types.js';
|
|
3
4
|
import { formatMessageDate, formatPayloadForCommandInput } from '../utils.js';
|
|
4
|
-
import { MessagePayloadDetail } from './MessagePayloadDetail.js';
|
|
5
|
-
import { ResizeHandle } from './ResizeHandle.js';
|
|
6
|
-
import { ScrollArea } from './ui/ScrollArea.js';
|
|
7
|
-
import { SendIcon } from './icons.js';
|
|
8
|
-
import { IconButton } from './ui/IconButton.js';
|
|
9
5
|
|
|
10
6
|
type MessageDetailsPaneProps = {
|
|
11
|
-
selectedMessage: MessageEntry
|
|
12
|
-
isOpen: boolean;
|
|
13
|
-
isNarrowViewport: boolean;
|
|
14
|
-
activeResizeHandle: ResizeHandleId | null;
|
|
7
|
+
selectedMessage: MessageEntry;
|
|
15
8
|
onClose: () => void;
|
|
16
9
|
onUseMessage: (message: MessageEntry) => void;
|
|
17
|
-
onResizeStart: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
18
10
|
};
|
|
19
11
|
|
|
20
12
|
export const MessageDetailsPane = ({
|
|
21
13
|
selectedMessage,
|
|
22
|
-
isOpen,
|
|
23
|
-
isNarrowViewport,
|
|
24
|
-
activeResizeHandle,
|
|
25
14
|
onClose,
|
|
26
15
|
onUseMessage,
|
|
27
|
-
onResizeStart,
|
|
28
16
|
}: MessageDetailsPaneProps) => {
|
|
29
|
-
const isHidden = !isOpen || !selectedMessage;
|
|
30
|
-
|
|
31
17
|
return (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
}}
|
|
58
|
-
>
|
|
59
|
-
<SendIcon />
|
|
60
|
-
</IconButton>
|
|
18
|
+
<section className="dev-host-pane">
|
|
19
|
+
<header className="dev-host-pane-header">
|
|
20
|
+
<h2 className="dev-host-pane-title">Message Details</h2>
|
|
21
|
+
<div className="dev-host-pane-actions">
|
|
22
|
+
<Button
|
|
23
|
+
variant="ghost"
|
|
24
|
+
size="icon"
|
|
25
|
+
onClick={() => onUseMessage(selectedMessage)}
|
|
26
|
+
aria-label="Use message in dispatcher"
|
|
27
|
+
title="Use message in dispatcher"
|
|
28
|
+
>
|
|
29
|
+
<Send />
|
|
30
|
+
</Button>
|
|
31
|
+
<Button
|
|
32
|
+
variant="ghost"
|
|
33
|
+
size="icon"
|
|
34
|
+
onClick={onClose}
|
|
35
|
+
aria-label="Close message details"
|
|
36
|
+
title="Close message details"
|
|
37
|
+
>
|
|
38
|
+
<X />
|
|
39
|
+
</Button>
|
|
40
|
+
</div>
|
|
41
|
+
</header>
|
|
61
42
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
43
|
+
<ScrollArea className="dev-host-scroll">
|
|
44
|
+
<div className="dev-host-details">
|
|
45
|
+
<div className="dev-host-detail-section">
|
|
46
|
+
<span className="dev-host-label">Date</span>
|
|
47
|
+
<div className="dev-host-detail-value">{formatMessageDate(selectedMessage.date)}</div>
|
|
48
|
+
</div>
|
|
49
|
+
<div className="dev-host-detail-section">
|
|
50
|
+
<span className="dev-host-label">Type</span>
|
|
51
|
+
<div className="dev-host-detail-value">{selectedMessage.type}</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div className="dev-host-detail-section">
|
|
54
|
+
<span className="dev-host-label">Payload</span>
|
|
55
|
+
<div className="dev-host-detail-payload">
|
|
56
|
+
{typeof selectedMessage.payload === 'object' && selectedMessage.payload !== null ? (
|
|
57
|
+
<JsonInspector data={selectedMessage.payload} defaultExpandedDepth={2} />
|
|
58
|
+
) : (
|
|
59
|
+
<pre className="m-0 whitespace-pre-wrap break-words">
|
|
60
|
+
{formatPayloadForCommandInput(selectedMessage.payload)}
|
|
61
|
+
</pre>
|
|
62
|
+
)}
|
|
69
63
|
</div>
|
|
70
64
|
</div>
|
|
71
|
-
|
|
72
|
-
<ScrollArea className="rz-sidebar-scroll">
|
|
73
|
-
{selectedMessage ? (
|
|
74
|
-
<div className="rz-message-detail">
|
|
75
|
-
<div className="rz-detail-section">
|
|
76
|
-
<div className="rz-label">Date</div>
|
|
77
|
-
<div className="rz-detail-value rz-detail-mono">
|
|
78
|
-
{formatMessageDate(selectedMessage.date)}
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
<div className="rz-detail-section">
|
|
83
|
-
<div className="rz-label">Type</div>
|
|
84
|
-
<div className="rz-detail-value rz-detail-mono">{selectedMessage.type}</div>
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
<div className="rz-detail-section">
|
|
88
|
-
<div className="rz-label">Payload</div>
|
|
89
|
-
<div className="rz-detail-payload">
|
|
90
|
-
<MessagePayloadDetail payload={selectedMessage.payload} />
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
) : (
|
|
95
|
-
<div className="rz-empty-state">Select a message to inspect its details.</div>
|
|
96
|
-
)}
|
|
97
|
-
</ScrollArea>
|
|
98
65
|
</div>
|
|
99
|
-
</
|
|
100
|
-
|
|
66
|
+
</ScrollArea>
|
|
67
|
+
</section>
|
|
101
68
|
);
|
|
102
69
|
};
|
|
103
70
|
|