feat(ui): add Session Changes sidebar section
Show session-level file changes in the right drawer with per-file +additions/-deletions and a Show changes button that appears only when diffs exist.
This commit is contained in:
@@ -304,6 +304,11 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
||||
return activeSessions().get(sessionId) ?? null
|
||||
})
|
||||
|
||||
const activeSessionDiffs = createMemo(() => {
|
||||
const session = activeSessionForInstance()
|
||||
return session?.diff
|
||||
})
|
||||
|
||||
const activeSessionUsage = createMemo(() => {
|
||||
const sessionId = activeSessionIdForInstance()
|
||||
if (!sessionId) return null
|
||||
@@ -960,6 +965,70 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
||||
)
|
||||
|
||||
const RightDrawerContent = () => {
|
||||
const renderSessionChanges = () => {
|
||||
const sessionId = activeSessionIdForInstance()
|
||||
if (!sessionId || sessionId === "info") {
|
||||
return <p class="text-xs text-secondary">{t("instanceShell.sessionChanges.noSessionSelected")}</p>
|
||||
}
|
||||
|
||||
const diffs = activeSessionDiffs()
|
||||
if (diffs === undefined) {
|
||||
return <p class="text-xs text-secondary">{t("instanceShell.sessionChanges.loading")}</p>
|
||||
}
|
||||
|
||||
if (!Array.isArray(diffs) || diffs.length === 0) {
|
||||
return <p class="text-xs text-secondary">{t("instanceShell.sessionChanges.empty")}</p>
|
||||
}
|
||||
|
||||
const sorted = [...diffs].sort((a, b) => String(a.file || "").localeCompare(String(b.file || "")))
|
||||
const totals = sorted.reduce(
|
||||
(acc, item) => {
|
||||
acc.additions += typeof item.additions === "number" ? item.additions : 0
|
||||
acc.deletions += typeof item.deletions === "number" ? item.deletions : 0
|
||||
return acc
|
||||
},
|
||||
{ additions: 0, deletions: 0 },
|
||||
)
|
||||
|
||||
return (
|
||||
<div class="flex flex-col gap-3 min-h-0">
|
||||
<div class="flex items-center justify-between gap-2 text-[11px] text-secondary">
|
||||
<span>{t("instanceShell.sessionChanges.filesChanged", { count: sorted.length })}</span>
|
||||
<span class="flex items-center gap-2">
|
||||
<span style={{ color: "var(--session-status-idle-fg)" }}>{`+${totals.additions}`}</span>
|
||||
<span style={{ color: "var(--session-status-working-fg)" }}>{`-${totals.deletions}`}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="rounded-md border border-base bg-surface-secondary p-2 max-h-[40vh] overflow-y-auto">
|
||||
<div class="flex flex-col">
|
||||
<For each={sorted}>
|
||||
{(item) => (
|
||||
<div class="py-2 border-b border-base last:border-b-0">
|
||||
<div class="text-xs font-mono text-primary truncate" title={item.file}>
|
||||
{item.file}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-[11px]">
|
||||
<span style={{ color: "var(--session-status-idle-fg)" }}>{`+${item.additions}`}</span>
|
||||
<span style={{ color: "var(--session-status-working-fg)" }}>{`-${item.deletions}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="button-tertiary w-full p-1.5 inline-flex items-center justify-center"
|
||||
onClick={() => undefined}
|
||||
>
|
||||
{t("instanceShell.sessionChanges.actions.show")}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const renderPlanSectionContent = () => {
|
||||
const sessionId = activeSessionIdForInstance()
|
||||
if (!sessionId || sessionId === "info") {
|
||||
@@ -1034,6 +1103,11 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
||||
}
|
||||
|
||||
const sections = [
|
||||
{
|
||||
id: "session-changes",
|
||||
labelKey: "instanceShell.rightPanel.sections.sessionChanges",
|
||||
render: renderSessionChanges,
|
||||
},
|
||||
{
|
||||
id: "plan",
|
||||
labelKey: "instanceShell.rightPanel.sections.plan",
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "Select a session to view messages",
|
||||
|
||||
"instanceShell.rightPanel.title": "Status Panel",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "Session Changes",
|
||||
"instanceShell.rightPanel.sections.plan": "Plan",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "Background Shells",
|
||||
"instanceShell.rightPanel.sections.mcp": "MCP Servers",
|
||||
"instanceShell.rightPanel.sections.lsp": "LSP Servers",
|
||||
"instanceShell.rightPanel.sections.plugins": "Plugins",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "Select a session to view changes.",
|
||||
"instanceShell.sessionChanges.loading": "Fetching session changes...",
|
||||
"instanceShell.sessionChanges.empty": "No session changes yet.",
|
||||
"instanceShell.sessionChanges.filesChanged": "{count} files changed",
|
||||
"instanceShell.sessionChanges.actions.show": "Show changes",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "Select a session to view plan.",
|
||||
"instanceShell.plan.empty": "Nothing planned yet.",
|
||||
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "Selecciona una sesión para ver mensajes",
|
||||
|
||||
"instanceShell.rightPanel.title": "Panel de estado",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "Cambios de sesion",
|
||||
"instanceShell.rightPanel.sections.plan": "Plan",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "Shells en segundo plano",
|
||||
"instanceShell.rightPanel.sections.mcp": "Servidores MCP",
|
||||
"instanceShell.rightPanel.sections.lsp": "Servidores LSP",
|
||||
"instanceShell.rightPanel.sections.plugins": "Plugins",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "Selecciona una sesion para ver los cambios.",
|
||||
"instanceShell.sessionChanges.loading": "Obteniendo cambios de la sesion...",
|
||||
"instanceShell.sessionChanges.empty": "Aun no hay cambios.",
|
||||
"instanceShell.sessionChanges.filesChanged": "{count} archivos cambiados",
|
||||
"instanceShell.sessionChanges.actions.show": "Mostrar cambios",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "Selecciona una sesión para ver el plan.",
|
||||
"instanceShell.plan.empty": "Aún no hay nada planificado.",
|
||||
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "Sélectionnez une session pour voir les messages",
|
||||
|
||||
"instanceShell.rightPanel.title": "Panneau d'état",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "Changements de session",
|
||||
"instanceShell.rightPanel.sections.plan": "Plan",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "Shells en arrière-plan",
|
||||
"instanceShell.rightPanel.sections.mcp": "Serveurs MCP",
|
||||
"instanceShell.rightPanel.sections.lsp": "Serveurs LSP",
|
||||
"instanceShell.rightPanel.sections.plugins": "Plugins",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "Sélectionnez une session pour voir les changements.",
|
||||
"instanceShell.sessionChanges.loading": "Récupération des changements...",
|
||||
"instanceShell.sessionChanges.empty": "Aucun changement pour l'instant.",
|
||||
"instanceShell.sessionChanges.filesChanged": "{count} fichiers modifiés",
|
||||
"instanceShell.sessionChanges.actions.show": "Afficher les changements",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "Sélectionnez une session pour voir le plan.",
|
||||
"instanceShell.plan.empty": "Aucun plan pour l'instant.",
|
||||
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "メッセージを表示するにはセッションを選択してください",
|
||||
|
||||
"instanceShell.rightPanel.title": "ステータスパネル",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "セッション変更",
|
||||
"instanceShell.rightPanel.sections.plan": "計画",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "バックグラウンドシェル",
|
||||
"instanceShell.rightPanel.sections.mcp": "MCP サーバー",
|
||||
"instanceShell.rightPanel.sections.lsp": "LSP サーバー",
|
||||
"instanceShell.rightPanel.sections.plugins": "プラグイン",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "変更を表示するにはセッションを選択してください。",
|
||||
"instanceShell.sessionChanges.loading": "変更を取得中...",
|
||||
"instanceShell.sessionChanges.empty": "まだ変更はありません。",
|
||||
"instanceShell.sessionChanges.filesChanged": "{count} 個のファイルが変更されました",
|
||||
"instanceShell.sessionChanges.actions.show": "変更を表示",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "計画を表示するにはセッションを選択してください。",
|
||||
"instanceShell.plan.empty": "まだ計画はありません。",
|
||||
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "Выберите сессию, чтобы просмотреть сообщения",
|
||||
|
||||
"instanceShell.rightPanel.title": "Панель состояния",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "Изменения сессии",
|
||||
"instanceShell.rightPanel.sections.plan": "План",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "Фоновые Shell",
|
||||
"instanceShell.rightPanel.sections.mcp": "MCP-серверы",
|
||||
"instanceShell.rightPanel.sections.lsp": "LSP-серверы",
|
||||
"instanceShell.rightPanel.sections.plugins": "Плагины",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "Выберите сессию, чтобы просмотреть изменения.",
|
||||
"instanceShell.sessionChanges.loading": "Загрузка изменений...",
|
||||
"instanceShell.sessionChanges.empty": "Пока нет изменений.",
|
||||
"instanceShell.sessionChanges.filesChanged": "Изменено файлов: {count}",
|
||||
"instanceShell.sessionChanges.actions.show": "Показать изменения",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "Выберите сессию, чтобы просмотреть план.",
|
||||
"instanceShell.plan.empty": "Пока ничего не запланировано.",
|
||||
|
||||
|
||||
@@ -86,12 +86,19 @@ export const instanceMessages = {
|
||||
"instanceShell.empty.description": "选择会话以查看消息",
|
||||
|
||||
"instanceShell.rightPanel.title": "状态面板",
|
||||
"instanceShell.rightPanel.sections.sessionChanges": "会话更改",
|
||||
"instanceShell.rightPanel.sections.plan": "计划",
|
||||
"instanceShell.rightPanel.sections.backgroundProcesses": "后台 Shell",
|
||||
"instanceShell.rightPanel.sections.mcp": "MCP 服务器",
|
||||
"instanceShell.rightPanel.sections.lsp": "LSP 服务器",
|
||||
"instanceShell.rightPanel.sections.plugins": "插件",
|
||||
|
||||
"instanceShell.sessionChanges.noSessionSelected": "选择会话以查看更改。",
|
||||
"instanceShell.sessionChanges.loading": "正在获取会话更改...",
|
||||
"instanceShell.sessionChanges.empty": "暂无会话更改。",
|
||||
"instanceShell.sessionChanges.filesChanged": "已更改 {count} 个文件",
|
||||
"instanceShell.sessionChanges.actions.show": "显示更改",
|
||||
|
||||
"instanceShell.plan.noSessionSelected": "选择会话以查看计划。",
|
||||
"instanceShell.plan.empty": "暂无计划。",
|
||||
|
||||
|
||||
Reference in New Issue
Block a user