Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/app/src/components/dialog-select-file.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Entry = {
type: EntryType
title: string
description?: string
keywords?: string
keybind?: string
category: string
option?: CommandOption
Expand Down Expand Up @@ -62,6 +63,7 @@ const createCommandEntry = (option: CommandOption, category: string): Entry => (
type: "command",
title: option.title,
description: option.description,
keywords: option.keywords,
keybind: option.keybind,
category,
option,
Expand Down Expand Up @@ -392,7 +394,7 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil
loadingMessage={language.t("common.loading")}
items={items}
key={(item) => item.id}
filterKeys={["title", "description", "category"]}
filterKeys={["title", "description", "keywords", "category"]}
groupBy={grouped() ? (item) => item.category : () => ""}
onMove={handleMove}
onSelect={handleSelect}
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/context/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface CommandOption {
id: string
title: string
description?: string
keywords?: string
category?: string
keybind?: KeybindConfig
slash?: string
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const dict = {
"theme.scheme.dark": "داكن",
"command.sidebar.toggle": "تبديل الشريط الجانبي",
"command.project.open": "فتح مشروع",
"command.project.close": "إغلاق مشروع",
"command.provider.connect": "اتصال بموفر",
"command.server.switch": "تبديل الخادم",
"command.settings.open": "فتح الإعدادات",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const dict = {
"theme.scheme.dark": "Escuro",
"command.sidebar.toggle": "Alternar barra lateral",
"command.project.open": "Abrir projeto",
"command.project.close": "Fechar projeto",
"command.provider.connect": "Conectar provedor",
"command.server.switch": "Trocar servidor",
"command.settings.open": "Abrir configurações",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const dict = {

"command.sidebar.toggle": "Prikaži/sakrij bočnu traku",
"command.project.open": "Otvori projekat",
"command.project.close": "Zatvori projekat",
"command.provider.connect": "Poveži provajdera",
"command.server.switch": "Promijeni server",
"command.settings.open": "Otvori postavke",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const dict = {

"command.sidebar.toggle": "Skift sidebjælke",
"command.project.open": "Åbn projekt",
"command.project.close": "Luk projekt",
"command.provider.connect": "Tilslut udbyder",
"command.server.switch": "Skift server",
"command.settings.open": "Åbn indstillinger",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const dict = {
"theme.scheme.dark": "Dunkel",
"command.sidebar.toggle": "Seitenleiste umschalten",
"command.project.open": "Projekt öffnen",
"command.project.close": "Projekt schließen",
"command.provider.connect": "Anbieter verbinden",
"command.server.switch": "Server wechseln",
"command.settings.open": "Einstellungen öffnen",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export const dict = {

"command.sidebar.toggle": "Toggle sidebar",
"command.project.open": "Open project",
"command.project.close": "Close project",
"command.project.close.description": "Close the current project",
"command.provider.connect": "Connect provider",
"command.server.switch": "Switch server",
"command.settings.open": "Open settings",
Expand Down Expand Up @@ -347,6 +349,11 @@ export const dict = {
"dialog.project.edit.worktree.startup": "Workspace startup script",
"dialog.project.edit.worktree.startup.description": "Runs after creating a new workspace (worktree).",
"dialog.project.edit.worktree.startup.placeholder": "e.g. bun install",
"dialog.project.close.title": "Close project",
"dialog.project.close.confirm": 'Close project "{{name}}"?',
"dialog.project.close.sessions.one": "This project has 1 active session.",
"dialog.project.close.sessions.many": "This project has {{count}} active sessions.",
"dialog.project.close.note": "You can reopen the project later from the command palette or sidebar.",

"dialog.releaseNotes.action.getStarted": "Get started",
"dialog.releaseNotes.action.next": "Next",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const dict = {

"command.sidebar.toggle": "Alternar barra lateral",
"command.project.open": "Abrir proyecto",
"command.project.close": "Cerrar proyecto",
"command.provider.connect": "Conectar proveedor",
"command.server.switch": "Cambiar servidor",
"command.settings.open": "Abrir ajustes",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const dict = {
"theme.scheme.dark": "Sombre",
"command.sidebar.toggle": "Basculer la barre latérale",
"command.project.open": "Ouvrir un projet",
"command.project.close": "Fermer le projet",
"command.provider.connect": "Connecter un fournisseur",
"command.server.switch": "Changer de serveur",
"command.settings.open": "Ouvrir les paramètres",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const dict = {
"theme.scheme.dark": "ダーク",
"command.sidebar.toggle": "サイドバーの切り替え",
"command.project.open": "プロジェクトを開く",
"command.project.close": "プロジェクトを閉じる",
"command.provider.connect": "プロバイダーに接続",
"command.server.switch": "サーバーの切り替え",
"command.settings.open": "設定を開く",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const dict = {
"theme.scheme.dark": "다크",
"command.sidebar.toggle": "사이드바 토글",
"command.project.open": "프로젝트 열기",
"command.project.close": "프로젝트 닫기",
"command.provider.connect": "공급자 연결",
"command.server.switch": "서버 전환",
"command.settings.open": "설정 열기",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const dict = {

"command.sidebar.toggle": "Veksle sidepanel",
"command.project.open": "Åpne prosjekt",
"command.project.close": "Lukk prosjekt",
"command.provider.connect": "Koble til leverandør",
"command.server.switch": "Bytt server",
"command.settings.open": "Åpne innstillinger",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const dict = {
"theme.scheme.dark": "Ciemny",
"command.sidebar.toggle": "Przełącz pasek boczny",
"command.project.open": "Otwórz projekt",
"command.project.close": "Zamknij projekt",
"command.provider.connect": "Połącz dostawcę",
"command.server.switch": "Przełącz serwer",
"command.settings.open": "Otwórz ustawienia",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const dict = {

"command.sidebar.toggle": "Переключить боковую панель",
"command.project.open": "Открыть проект",
"command.project.close": "Закрыть проект",
"command.provider.connect": "Подключить провайдера",
"command.server.switch": "Переключить сервер",
"command.settings.open": "Открыть настройки",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/th.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const dict = {

"command.sidebar.toggle": "สลับแถบข้าง",
"command.project.open": "เปิดโปรเจกต์",
"command.project.close": "ปิดโปรเจกต์",
"command.provider.connect": "เชื่อมต่อผู้ให้บริการ",
"command.server.switch": "สลับเซิร์ฟเวอร์",
"command.settings.open": "เปิดการตั้งค่า",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const dict = {

"command.sidebar.toggle": "Kenar çubuğunu aç/kapat",
"command.project.open": "Proje aç",
"command.project.close": "Projeyi kapat",
"command.provider.connect": "Sağlayıcı bağla",
"command.server.switch": "Sunucu değiştir",
"command.settings.open": "Ayarları aç",
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const dict = {
"command.sidebar.toggle": "切换侧边栏",

"command.project.open": "打开项目",
"command.project.close": "关闭项目",

"command.provider.connect": "连接提供商",

Expand Down
1 change: 1 addition & 0 deletions packages/app/src/i18n/zht.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const dict = {

"command.sidebar.toggle": "切換側邊欄",
"command.project.open": "開啟專案",
"command.project.close": "關閉專案",
"command.provider.connect": "連接提供者",
"command.server.switch": "切換伺服器",
"command.settings.open": "開啟設定",
Expand Down
49 changes: 24 additions & 25 deletions packages/app/src/pages/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import {
import { workspaceOpenState } from "./layout/sidebar-workspace-helpers"
import { ProjectDragOverlay, SortableProject, type ProjectSidebarContext } from "./layout/sidebar-project"
import { SidebarContent } from "./layout/sidebar-shell"
import { closeProject as runProjectClose } from "./layout/project-close"

export default function Layout(props: ParentProps) {
const [store, setStore, , ready] = persisted(
Expand Down Expand Up @@ -959,6 +960,19 @@ export default function Layout(props: ParentProps) {
keybind: "mod+o",
onSelect: () => chooseProject(),
},
{
id: "project.close",
title: language.t("command.project.close"),
description: language.t("command.project.close.description"),
keywords: "remove workspace",
category: language.t("command.category.project"),
disabled: !currentProject(),
onSelect: () => {
const project = currentProject()
if (!project) return
close(project.worktree)
},
},
{
id: "provider.connect",
title: language.t("command.provider.connect"),
Expand Down Expand Up @@ -1317,30 +1331,15 @@ export default function Layout(props: ParentProps) {
setWorkspaceName(directory, next, projectId, branch)
}

function closeProject(directory: string) {
const list = layout.projects.list()
const index = list.findIndex((x) => x.worktree === directory)
const active = currentProject()?.worktree === directory
if (index === -1) return
const next = list[index + 1]

if (!active) {
layout.projects.close(directory)
return
}

if (!next) {
layout.projects.close(directory)
navigate("/")
return
}

navigateWithSidebarReset(`/${base64Encode(next.worktree)}/session`)
layout.projects.close(directory)
queueMicrotask(() => {
void navigateToProject(next.worktree)
const close = (directory: string) =>
runProjectClose({
directory,
list: layout.projects.list(),
current: currentProject()?.worktree,
close: layout.projects.close,
go: navigateWithSidebarReset,
open: navigateToProject,
})
}

function toggleProjectWorkspaces(project: LocalProject) {
const enabled = layout.sidebar.workspaces(project.worktree)()
Expand Down Expand Up @@ -1882,7 +1881,7 @@ export default function Layout(props: ParentProps) {
onProjectFocus: (worktree) => aim.activate(worktree),
navigateToProject,
openSidebar: () => layout.sidebar.open(),
closeProject,
closeProject: close,
showEditProjectDialog,
toggleProjectWorkspaces,
workspacesEnabled: (project) => project.vcs === "git" && layout.sidebar.workspaces(project.worktree)(),
Expand Down Expand Up @@ -2016,7 +2015,7 @@ export default function Layout(props: ParentProps) {
<DropdownMenu.Item
data-action="project-close-menu"
data-project={base64Encode(p().worktree)}
onSelect={() => closeProject(p().worktree)}
onSelect={() => close(p().worktree)}
>
<DropdownMenu.ItemLabel>{language.t("common.close")}</DropdownMenu.ItemLabel>
</DropdownMenu.Item>
Expand Down
37 changes: 37 additions & 0 deletions packages/app/src/pages/layout/project-close.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, expect, test } from "bun:test"
import { closeProject } from "./project-close"

describe("closeProject", () => {
test("closes inactive project without navigation", () => {
const calls = { close: [] as string[], nav: [] as string[], open: [] as string[] }
closeProject({
directory: "/b",
list: [
{ worktree: "/a", expanded: false },
{ worktree: "/b", expanded: false },
],
current: "/a",
close: (directory) => calls.close.push(directory),
navigate: (href) => calls.nav.push(href),
open: (directory) => {
calls.open.push(directory)
},
})
expect(calls).toEqual({ close: ["/b"], nav: [], open: [] })
})

test("navigates home when closing the active last project", () => {
const calls = { close: [] as string[], nav: [] as string[], open: [] as string[] }
closeProject({
directory: "/a",
list: [{ worktree: "/a", expanded: false }],
current: "/a",
close: (directory) => calls.close.push(directory),
navigate: (href) => calls.nav.push(href),
open: (directory) => {
calls.open.push(directory)
},
})
expect(calls).toEqual({ close: ["/a"], nav: ["/"], open: [] })
})
})
37 changes: 37 additions & 0 deletions packages/app/src/pages/layout/project-close.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { base64Encode } from "@opencode-ai/util/encode"
import type { LocalProject } from "@/context/layout"

type Nav = {
directory: string
list: LocalProject[]
current?: string
close: (directory: string) => void
go?: (href: string) => void
navigate?: (href: string) => void
open: (directory: string) => Promise<void> | void
}

export function closeProject(input: Nav) {
const go = input.go ?? input.navigate
const index = input.list.findIndex((x) => x.worktree === input.directory)
const active = input.current === input.directory
if (index === -1) return
const next = input.list[index + 1]

if (!active) {
input.close(input.directory)
return
}

if (!next) {
input.close(input.directory)
go?.("/")
return
}

go?.(`/${base64Encode(next.worktree)}/session`)
input.close(input.directory)
queueMicrotask(() => {
void input.open(next.worktree)
})
}
Loading