refactor: restructure session sidebar layout
This commit is contained in:
@@ -53,7 +53,7 @@ export default function AgentSelector(props: AgentSelectorProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="sidebar-selector">
|
||||
<Select
|
||||
value={availableAgents().find((a) => a.name === props.currentAgent)}
|
||||
onChange={handleChange}
|
||||
@@ -108,7 +108,7 @@ export default function AgentSelector(props: AgentSelectorProps) {
|
||||
</Select.Content>
|
||||
</Select.Portal>
|
||||
</Select>
|
||||
<span class="hint">
|
||||
<span class="hint sidebar-selector-hint">
|
||||
<Kbd shortcut="cmd+shift+a" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -63,7 +63,7 @@ export default function ModelSelector(props: ModelSelectorProps) {
|
||||
})
|
||||
|
||||
return (
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="sidebar-selector">
|
||||
<Combobox<FlatModel>
|
||||
value={currentModelValue()}
|
||||
onChange={handleChange}
|
||||
@@ -97,14 +97,14 @@ export default function ModelSelector(props: ModelSelectorProps) {
|
||||
</Combobox.Item>
|
||||
)}
|
||||
>
|
||||
<Combobox.Control class="relative" data-model-selector-control>
|
||||
<Combobox.Control class="relative w-full" data-model-selector-control>
|
||||
<Combobox.Input class="sr-only" data-model-selector />
|
||||
<Combobox.Trigger
|
||||
ref={triggerRef}
|
||||
class="selector-trigger"
|
||||
>
|
||||
<div class="selector-trigger-label">
|
||||
<span class="selector-trigger-primary">
|
||||
<div class="selector-trigger-label selector-trigger-label--stacked">
|
||||
<span class="selector-trigger-primary selector-trigger-primary--align-left">
|
||||
Model: {currentModelValue()?.name ?? "None"}
|
||||
</span>
|
||||
{currentModelValue() && (
|
||||
@@ -132,7 +132,7 @@ export default function ModelSelector(props: ModelSelectorProps) {
|
||||
</Combobox.Content>
|
||||
</Combobox.Portal>
|
||||
</Combobox>
|
||||
<span class="hint">
|
||||
<span class="hint sidebar-selector-hint">
|
||||
<Kbd shortcut="cmd+shift+m" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { createSignal, Show, onMount, For, onCleanup } from "solid-js"
|
||||
import AgentSelector from "./agent-selector"
|
||||
import ModelSelector from "./model-selector"
|
||||
import UnifiedPicker from "./unified-picker"
|
||||
import { addToHistory, getHistory } from "../stores/message-history"
|
||||
import { getAttachments, addAttachment, clearAttachments, removeAttachment } from "../stores/attachments"
|
||||
@@ -17,10 +15,6 @@ interface PromptInputProps {
|
||||
sessionId: string
|
||||
onSend: (prompt: string, attachments: Attachment[]) => Promise<void>
|
||||
disabled?: boolean
|
||||
agent: string
|
||||
model: { providerId: string; modelId: string }
|
||||
onAgentChange: (agent: string) => Promise<void>
|
||||
onModelChange: (model: { providerId: string; modelId: string }) => Promise<void>
|
||||
escapeInDebounce?: boolean
|
||||
}
|
||||
|
||||
@@ -730,37 +724,25 @@ export default function PromptInput(props: PromptInputProps) {
|
||||
</button>
|
||||
</div>
|
||||
<div class="prompt-input-hints">
|
||||
<HintRow>
|
||||
<Show
|
||||
when={props.escapeInDebounce}
|
||||
fallback={
|
||||
<>
|
||||
<Kbd>Enter</Kbd> to send • <Kbd>Shift+Enter</Kbd> for new line • <Kbd>@</Kbd> for files/agents •{" "}
|
||||
<Kbd>↑↓</Kbd> for history
|
||||
<Show when={attachments().length > 0}>
|
||||
<span class="ml-2 text-xs" style="color: var(--text-muted);">• {attachments().length} file(s) attached</span>
|
||||
</Show>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span class="font-medium" style="color: var(--status-warning);">
|
||||
Press <Kbd>Esc</Kbd> again to abort session
|
||||
</span>
|
||||
</Show>
|
||||
</HintRow>
|
||||
<div class="flex items-center gap-2">
|
||||
<AgentSelector
|
||||
instanceId={props.instanceId}
|
||||
sessionId={props.sessionId}
|
||||
currentAgent={props.agent}
|
||||
onAgentChange={props.onAgentChange}
|
||||
/>
|
||||
<ModelSelector
|
||||
instanceId={props.instanceId}
|
||||
sessionId={props.sessionId}
|
||||
currentModel={props.model}
|
||||
onModelChange={props.onModelChange}
|
||||
/>
|
||||
<div class="flex justify-end">
|
||||
<HintRow>
|
||||
<Show
|
||||
when={props.escapeInDebounce}
|
||||
fallback={
|
||||
<>
|
||||
<Kbd>Enter</Kbd> to send • <Kbd>Shift+Enter</Kbd> for new line • <Kbd>@</Kbd> for files/agents •{" "}
|
||||
<Kbd>↑↓</Kbd> for history
|
||||
<Show when={attachments().length > 0}>
|
||||
<span class="ml-2 text-xs" style="color: var(--text-muted);">• {attachments().length} file(s) attached</span>
|
||||
</Show>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span class="font-medium" style="color: var(--status-warning);">
|
||||
Press <Kbd>Esc</Kbd> again to abort session
|
||||
</span>
|
||||
</Show>
|
||||
</HintRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, For, Show, createSignal, createEffect, onCleanup, onMount, createMemo } from "solid-js"
|
||||
import { Component, For, Show, createSignal, createEffect, onCleanup, onMount, createMemo, JSX } from "solid-js"
|
||||
import type { Session } from "../types/session"
|
||||
import { MessageSquare, Info, Plus, X } from "lucide-solid"
|
||||
import KeyboardHint from "./keyboard-hint"
|
||||
@@ -21,6 +21,11 @@ interface SessionListProps {
|
||||
onSelect: (sessionId: string) => void
|
||||
onClose: (sessionId: string) => void
|
||||
onNew: () => void
|
||||
showHeader?: boolean
|
||||
showFooter?: boolean
|
||||
headerContent?: JSX.Element
|
||||
footerContent?: JSX.Element
|
||||
onWidthChange?: (width: number) => void
|
||||
}
|
||||
|
||||
const MIN_WIDTH = 200
|
||||
@@ -57,6 +62,10 @@ const SessionList: Component<SessionListProps> = (props) => {
|
||||
window.localStorage.setItem(STORAGE_KEY, width.toString())
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
props.onWidthChange?.(sidebarWidth())
|
||||
})
|
||||
|
||||
const clampWidth = (width: number) => Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, width))
|
||||
|
||||
const removeMouseListeners = () => {
|
||||
@@ -194,14 +203,18 @@ const SessionList: Component<SessionListProps> = (props) => {
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<div class="session-list-header p-3 border-b border-base">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<h3 class="text-sm font-semibold text-primary">Sessions</h3>
|
||||
<KeyboardHint
|
||||
shortcuts={[keyboardRegistry.get("session-prev")!, keyboardRegistry.get("session-next")!].filter(Boolean)}
|
||||
/>
|
||||
<Show when={props.showHeader !== false}>
|
||||
<div class="session-list-header p-3 border-b border-base">
|
||||
{props.headerContent ?? (
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<h3 class="text-sm font-semibold text-primary">Sessions</h3>
|
||||
<KeyboardHint
|
||||
shortcuts={[keyboardRegistry.get("session-prev")!, keyboardRegistry.get("session-next")!].filter(Boolean)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div class="session-list flex-1 overflow-y-auto">
|
||||
<div class="session-section">
|
||||
@@ -289,17 +302,21 @@ const SessionList: Component<SessionListProps> = (props) => {
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<div class="session-list-footer p-3 border-t border-base">
|
||||
<button
|
||||
class="session-new-button w-full flex items-center gap-2 px-3 py-2 rounded-md transition-colors text-sm font-medium"
|
||||
onClick={props.onNew}
|
||||
title="New session (Cmd/Ctrl+T)"
|
||||
aria-label="New session"
|
||||
>
|
||||
<Plus class="w-4 h-4" />
|
||||
<span>New Session</span>
|
||||
</button>
|
||||
</div>
|
||||
<Show when={props.showFooter !== false}>
|
||||
<div class="session-list-footer p-3 border-t border-base">
|
||||
{props.footerContent ?? (
|
||||
<button
|
||||
class="session-new-button w-full flex items-center gap-2 px-3 py-2 rounded-md transition-colors text-sm font-medium"
|
||||
onClick={props.onNew}
|
||||
title="New session (Cmd/Ctrl+T)"
|
||||
aria-label="New session"
|
||||
>
|
||||
<Plus class="w-4 h-4" />
|
||||
<span>New Session</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user