Skip to content

Commit 541f2c0

Browse files
committed
cp dines
1 parent 69186c0 commit 541f2c0

1 file changed

Lines changed: 76 additions & 6 deletions

File tree

src/components/DevboxDetailPage.tsx

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,45 @@ export const DevboxDetailPage: React.FC<DevboxDetailPageProps> = ({ devbox: init
3939
const [showDetailedInfo, setShowDetailedInfo] = React.useState(false);
4040
const [detailScroll, setDetailScroll] = React.useState(0);
4141
const [showActions, setShowActions] = React.useState(false);
42+
const [selectedOperation, setSelectedOperation] = React.useState(0);
4243

4344
const selectedDevbox = initialDevbox;
4445

46+
const allOperations = [
47+
{ key: 'logs', label: 'View Logs', color: 'blue', icon: figures.info, shortcut: 'l' },
48+
{ key: 'exec', label: 'Execute Command', color: 'green', icon: figures.play, shortcut: 'e' },
49+
{ key: 'upload', label: 'Upload File', color: 'green', icon: figures.arrowUp, shortcut: 'u' },
50+
{ key: 'snapshot', label: 'Create Snapshot', color: 'yellow', icon: figures.circleFilled, shortcut: 'n' },
51+
{ key: 'ssh', label: 'SSH onto the box', color: 'cyan', icon: figures.arrowRight, shortcut: 's' },
52+
{ key: 'tunnel', label: 'Open Tunnel', color: 'magenta', icon: figures.pointerSmall, shortcut: 't' },
53+
{ key: 'suspend', label: 'Suspend Devbox', color: 'yellow', icon: figures.squareSmallFilled, shortcut: 'p' },
54+
{ key: 'resume', label: 'Resume Devbox', color: 'green', icon: figures.play, shortcut: 'r' },
55+
{ key: 'delete', label: 'Shutdown Devbox', color: 'red', icon: figures.cross, shortcut: 'd' },
56+
];
57+
58+
// Filter operations based on devbox status
59+
const operations = selectedDevbox ? allOperations.filter(op => {
60+
const status = selectedDevbox.status;
61+
62+
// When suspended: logs and resume
63+
if (status === 'suspended') {
64+
return op.key === 'resume' || op.key === 'logs';
65+
}
66+
67+
// When not running (shutdown, failure, etc): only logs
68+
if (status !== 'running' && status !== 'provisioning' && status !== 'initializing') {
69+
return op.key === 'logs';
70+
}
71+
72+
// When running: everything except resume
73+
if (status === 'running') {
74+
return op.key !== 'resume';
75+
}
76+
77+
// Default for transitional states (provisioning, initializing)
78+
return op.key === 'logs' || op.key === 'delete';
79+
}) : allOperations;
80+
4581
// Memoize time-based values to prevent re-rendering on every tick
4682
const formattedCreateTime = React.useMemo(
4783
() => selectedDevbox.create_time_ms ? new Date(selectedDevbox.create_time_ms).toLocaleString() : '',
@@ -80,17 +116,31 @@ export const DevboxDetailPage: React.FC<DevboxDetailPageProps> = ({ devbox: init
80116
return;
81117
}
82118

83-
// Operations selection mode
119+
// Main view input handling
84120
if (input === 'q' || key.escape) {
85121
console.clear();
86122
onBack();
87123
} else if (input === 'i') {
88124
setShowDetailedInfo(true);
89125
setDetailScroll(0);
90-
} else if (input === 'a') {
126+
} else if (key.upArrow && selectedOperation > 0) {
127+
setSelectedOperation(selectedOperation - 1);
128+
} else if (key.downArrow && selectedOperation < operations.length - 1) {
129+
setSelectedOperation(selectedOperation + 1);
130+
} else if (key.return || input === 'a') {
91131
console.clear();
92132
setShowActions(true);
93-
} else if (input === 'o') {
133+
} else if (input) {
134+
// Check if input matches any operation shortcut
135+
const matchedOpIndex = operations.findIndex(op => op.shortcut === input);
136+
if (matchedOpIndex !== -1) {
137+
setSelectedOperation(matchedOpIndex);
138+
console.clear();
139+
setShowActions(true);
140+
}
141+
}
142+
143+
if (input === 'o') {
94144
// Open in browser
95145
const url = `https://platform.runloop.ai/devboxes/${selectedDevbox.id}`;
96146
const openBrowser = async () => {
@@ -256,12 +306,15 @@ export const DevboxDetailPage: React.FC<DevboxDetailPageProps> = ({ devbox: init
256306
return lines;
257307
};
258308

259-
// Actions view
309+
// Actions view - show the DevboxActionsMenu when an action is triggered
260310
if (showActions) {
261311
return (
262312
<DevboxActionsMenu
263313
devbox={selectedDevbox}
264-
onBack={() => setShowActions(false)}
314+
onBack={() => {
315+
setShowActions(false);
316+
setSelectedOperation(0);
317+
}}
265318
breadcrumbItems={[
266319
{ label: 'Devboxes' },
267320
{ label: selectedDevbox.name || selectedDevbox.id },
@@ -419,9 +472,26 @@ export const DevboxDetailPage: React.FC<DevboxDetailPageProps> = ({ devbox: init
419472
</Box>
420473
)}
421474

475+
{/* Operations - inline display */}
476+
<Box flexDirection="column" marginTop={1}>
477+
<Text color="cyan" bold>{figures.play} Actions</Text>
478+
<Box flexDirection="column">
479+
{operations.map((op, index) => {
480+
const isSelected = index === selectedOperation;
481+
return (
482+
<Box key={op.key}>
483+
<Text color={isSelected ? 'cyan' : 'gray'}>{isSelected ? figures.pointer : ' '} </Text>
484+
<Text color={isSelected ? op.color : 'gray'} bold={isSelected}>{op.icon} {op.label}</Text>
485+
<Text color="gray" dimColor> [{op.shortcut}]</Text>
486+
</Box>
487+
);
488+
})}
489+
</Box>
490+
</Box>
491+
422492
<Box marginTop={1}>
423493
<Text color="gray" dimColor>
424-
[a] Actions • [i] Full Details • [o] Browser • [q] Back
494+
{figures.arrowUp}{figures.arrowDown} Navigate • [Enter] or [shortcut] Execute • [i] Full Details • [o] Browser • [q] Back
425495
</Text>
426496
</Box>
427497
</>

0 commit comments

Comments
 (0)