Skip to content

Commit cbd0ee2

Browse files
Add mobileFullscreen to settings dialogs and fix button layout (#163)
* Add mobileFullscreen to settings dialogs and fix button layout * Improve responsive layout in settings UI components * Fix null safety in SessionDetail
1 parent 2e634b5 commit cbd0ee2

8 files changed

Lines changed: 26 additions & 23 deletions

File tree

frontend/src/components/settings/AddMcpServerDialog.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export function AddMcpServerDialog({ open, onOpenChange, onUpdate }: AddMcpServe
179179

180180
return (
181181
<Dialog open={open} onOpenChange={handleClose}>
182-
<DialogContent className="max-w-3xl max-h-[90vh] sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
182+
<DialogContent mobileFullscreen className="sm:max-w-3xl sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
183183
<DialogHeader className="p-4 sm:p-6 border-b flex flex-row items-center justify-between space-y-0">
184184
<DialogTitle>Add MCP Server</DialogTitle>
185185
</DialogHeader>
@@ -366,12 +366,13 @@ export function AddMcpServerDialog({ open, onOpenChange, onUpdate }: AddMcpServe
366366
</div>
367367

368368
<DialogFooter className="p-3 sm:p-4 border-t gap-2">
369-
<Button variant="outline" onClick={handleClose}>
369+
<Button variant="outline" onClick={handleClose} className="flex-1 sm:flex-none">
370370
Cancel
371371
</Button>
372372
<Button
373373
onClick={handleAdd}
374374
disabled={!serverId || isPending}
375+
className="flex-1 sm:flex-none"
375376
>
376377
{isPending && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
377378
Add MCP Server

frontend/src/components/settings/AgentDialog.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ export function AgentDialog({ open, onOpenChange, onSubmit, editingAgent }: Agen
176176

177177
return (
178178
<Dialog open={open} onOpenChange={handleOpenChange}>
179-
<DialogContent className="max-w-2xl max-h-[90vh] sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
179+
<DialogContent mobileFullscreen className="sm:max-w-2xl sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
180180
<DialogHeader className="p-4 sm:p-6 border-b flex flex-row items-center justify-between space-y-0">
181181
<DialogTitle>{editingAgent ? 'Edit Agent' : 'Create Agent'}</DialogTitle>
182182
</DialogHeader>
@@ -522,12 +522,13 @@ export function AgentDialog({ open, onOpenChange, onSubmit, editingAgent }: Agen
522522
</div>
523523

524524
<DialogFooter className="p-3 sm:p-4 border-t gap-2">
525-
<Button variant="outline" onClick={() => handleOpenChange(false)}>
525+
<Button variant="outline" onClick={() => handleOpenChange(false)} className="flex-1 sm:flex-none">
526526
Cancel
527527
</Button>
528528
<Button
529529
onClick={() => form.handleSubmit(handleSubmit)()}
530530
disabled={!form.formState.isValid}
531+
className="flex-1 sm:flex-none"
531532
>
532533
{editingAgent ? 'Update' : 'Create'}
533534
</Button>

frontend/src/components/settings/AgentsMdEditor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ export function AgentsMdEditor() {
8484

8585
return (
8686
<div className="space-y-4">
87-
<div className="flex items-center justify-between">
87+
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
8888
<div>
8989
<p className="text-sm text-muted-foreground">
9090
Global instructions for AI agents. This file is merged with repository-specific AGENTS.md files.
9191
</p>
9292
</div>
93-
<div className="flex gap-2">
93+
<div className="flex gap-2 flex-shrink-0">
9494
<Button
9595
variant="outline"
9696
size="sm"
@@ -122,7 +122,7 @@ export function AgentsMdEditor() {
122122
<Textarea
123123
value={content}
124124
onChange={(e) => handleContentChange(e.target.value)}
125-
className="font-mono md:text-sm min-h-[300px] resize-y"
125+
className="font-mono text-xs sm:text-sm min-h-[300px] resize-y"
126126
placeholder="# Agent Instructions&#10;&#10;Add global instructions for AI agents here..."
127127
/>
128128

frontend/src/components/settings/CommandDialog.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function CommandDialog({
9999

100100
return (
101101
<Dialog open={open} onOpenChange={handleOpenChange}>
102-
<DialogContent className="max-w-3xl max-h-[90vh] sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
102+
<DialogContent mobileFullscreen className="sm:max-w-3xl sm:max-h-[85vh] gap-0 flex flex-col p-0 md:p-6">
103103
<DialogHeader className="p-4 sm:p-6 border-b flex flex-row items-center justify-between space-y-0">
104104
<DialogTitle>
105105
{editingCommand ? "Edit Command" : "Create Command"}
@@ -251,10 +251,10 @@ export function CommandDialog({
251251
</div>
252252

253253
<DialogFooter className="p-3 sm:p-4 border-t gap-2">
254-
<Button variant="outline" onClick={() => handleOpenChange(false)}>
254+
<Button variant="outline" onClick={() => handleOpenChange(false)} className="flex-1 sm:flex-none">
255255
Cancel
256256
</Button>
257-
<Button onClick={() => form.handleSubmit(handleSubmit)()} disabled={!form.formState.isValid}>
257+
<Button onClick={() => form.handleSubmit(handleSubmit)()} disabled={!form.formState.isValid} className="flex-1 sm:flex-none">
258258
{editingCommand ? "Update" : "Create"}
259259
</Button>
260260
</DialogFooter>

frontend/src/components/settings/CreateConfigDialog.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function CreateConfigDialog({ isOpen, onOpenChange, onCreate, isUpdating
104104

105105
return (
106106
<Dialog open={isOpen} onOpenChange={onOpenChange}>
107-
<DialogContent className="max-w-2xl max-h-[90vh] sm:max-h-[85vh] flex flex-col">
107+
<DialogContent mobileFullscreen className="sm:max-w-2xl sm:max-h-[85vh] flex flex-col">
108108
<DialogHeader className="flex-shrink-0">
109109
<DialogTitle>Create OpenCode Config</DialogTitle>
110110
</DialogHeader>
@@ -160,14 +160,15 @@ export function CreateConfigDialog({ isOpen, onOpenChange, onCreate, isUpdating
160160
</div>
161161
</div>
162162

163-
<div className="flex justify-end gap-2 flex-shrink-0 pt-4 border-t">
164-
<Button variant="outline" onClick={() => onOpenChange(false)}>
163+
<div className="flex flex-row sm:flex-row justify-end gap-2 flex-shrink-0 pt-4 border-t">
164+
<Button variant="outline" onClick={() => onOpenChange(false)} className="flex-1 sm:flex-none">
165165
Cancel
166166
</Button>
167167
<Button
168168
type="button"
169169
onClick={(e) => handleSubmit(e)}
170170
disabled={isUpdating || !name.trim() || !content.trim()}
171+
className="flex-1 sm:flex-none"
171172
>
172173
{isUpdating && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
173174
Create

frontend/src/components/settings/OpenCodeConfigManager.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState, useEffect, useRef } from 'react'
22
import { cn } from '@/lib/utils'
3-
import { Loader2, Plus, Trash2, Edit, StarOff, Download, RotateCcw, FileText, ArrowUpCircle, History } from 'lucide-react'
3+
import { Loader2, Plus, Trash2, Edit, StarOff, Download, RotateCcw, FileText, ArrowUpCircle, History, ChevronDown } from 'lucide-react'
44
import { Button } from '@/components/ui/button'
55
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
66
import { Label } from '@/components/ui/label'
@@ -477,7 +477,7 @@ export function OpenCodeConfigManager() {
477477
<CardHeader className="pb-3">
478478
<div className="flex items-center justify-between">
479479
<div className="flex items-center gap-2 flex-wrap">
480-
<CardTitle className="text-base">{config.name}</CardTitle>
480+
<CardTitle className="text-sm sm:text-base">{config.name}</CardTitle>
481481
{config.isDefault && (
482482
<Badge variant="default" className="text-green-500 bg-green-500/10">
483483
Current
@@ -572,7 +572,7 @@ export function OpenCodeConfigManager() {
572572
<FileText className="h-4 w-4 text-blue-500" />
573573
<h4 className="text-sm font-medium truncate">Global Agent Instructions (AGENTS.md)</h4>
574574
</div>
575-
<Edit className={`h-4 w-4 transition-transform ${expandedSections.agentsMd ? 'rotate-90' : ''}`} />
575+
<ChevronDown className={`h-4 w-4 transition-transform ${expandedSections.agentsMd ? 'rotate-90' : ''}`} />
576576
</button>
577577
<div className={`${expandedSections.agentsMd ? 'block' : 'hidden'} border-t border-border`}>
578578
<div className="p-4">
@@ -581,15 +581,15 @@ export function OpenCodeConfigManager() {
581581
</div>
582582
</div>
583583

584-
<h3 className="text-lg font-semibold mb-4">Configure Commands, Agents & MCP Servers</h3>
584+
<h3 className="text-base sm:text-lg font-semibold mb-4">Configure Commands, Agents & MCP Servers</h3>
585585
<p className="text-sm text-muted-foreground mb-6">
586586
Add custom commands, agents, and MCP servers to your OpenCode configurations. Select a configuration below to edit its settings.
587587
</p>
588588

589589
{configs.length > 0 && (
590590
<div className="space-y-6">
591591
<div className='px-1'>
592-
<Label className="text-base font-medium">Select Configuration to Edit</Label>
592+
<Label className="text-sm sm:text-base font-medium">Select Configuration to Edit</Label>
593593
<Select
594594
onValueChange={(value) => {
595595
const config = configs.find(c => c.name === value)
@@ -632,7 +632,7 @@ export function OpenCodeConfigManager() {
632632
{Object.keys((selectedConfig.content?.command as Record<string, Command> | undefined) ?? {}).length} configured
633633
</span>
634634
</div>
635-
<Edit className={`h-4 w-4 transition-transform ${expandedSections.commands ? 'rotate-90' : ''}`} />
635+
<ChevronDown className={`h-4 w-4 transition-transform ${expandedSections.commands ? 'rotate-90' : ''}`} />
636636
</button>
637637
<div className={`${expandedSections.commands ? 'block' : 'hidden'} border-t border-border`}>
638638
<div className="p-1 sm:p-4 max-h-[50vh] overflow-y-auto">
@@ -669,7 +669,7 @@ export function OpenCodeConfigManager() {
669669
{Object.keys((selectedConfig.content?.agent as Record<string, Agent> | undefined) ?? {}).length} configured
670670
</span>
671671
</div>
672-
<Edit className={`h-4 w-4 transition-transform ${expandedSections.agents ? 'rotate-90' : ''}`} />
672+
<ChevronDown className={`h-4 w-4 transition-transform ${expandedSections.agents ? 'rotate-90' : ''}`} />
673673
</button>
674674
<div className={`${expandedSections.agents ? 'block' : 'hidden'} border-t border-border`}>
675675
<div className="p-4 max-h-[50vh] overflow-y-auto">
@@ -706,7 +706,7 @@ export function OpenCodeConfigManager() {
706706
{Object.keys((selectedConfig.content?.mcp as Record<string, unknown> | undefined) ?? {}).length} configured
707707
</span>
708708
</div>
709-
<Edit className={`h-4 w-4 transition-transform ${expandedSections.mcp ? 'rotate-90' : ''}`} />
709+
<ChevronDown className={`h-4 w-4 transition-transform ${expandedSections.mcp ? 'rotate-90' : ''}`} />
710710
</button>
711711
<div className={`${expandedSections.mcp ? 'block' : 'hidden'} border-t border-border`}>
712712
<div className="p-4 max-h-[50vh] overflow-y-auto">

frontend/src/components/ui/dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const DialogFooter = ({
9999
}: React.HTMLAttributes<HTMLDivElement>) => (
100100
<div
101101
className={cn(
102-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
102+
"flex flex-row sm:flex-row sm:justify-end sm:space-x-2 gap-2",
103103
className
104104
)}
105105
{...props}

frontend/src/pages/SessionDetail.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export function SessionDetail() {
138138
const sessionStatus = useSessionStatusForSession(sessionId);
139139
const isSessionActive = sessionStatus.type === 'busy' || sessionStatus.type === 'retry';
140140
const lastAssistantMessage = messages?.filter(m => m.info.role === 'assistant').at(-1);
141-
const lastAssistantText = lastAssistantMessage?.parts.filter(p => p.type === 'text').map(p => p.text).join('\n\n') || '';
141+
const lastAssistantText = (lastAssistantMessage?.parts ?? []).filter(p => p.type === 'text').map(p => p.text).join('\n\n') || '';
142142
const hasIncompleteMessages = lastAssistantMessage ? !('completed' in lastAssistantMessage.info.time && lastAssistantMessage.info.time.completed) : false;
143143
const hasActiveStream = hasIncompleteMessages && isSessionActive;
144144

0 commit comments

Comments
 (0)