ikanban-web 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{ghostty-web-CkHg_Jfr.js → ghostty-web-BOsxUEnx.js} +1 -1
- package/dist/assets/home-DmwjxlRp.js +1 -0
- package/dist/assets/{index-n2BMSLCz.js → index-CE2ZqGRp.js} +107 -107
- package/dist/assets/{index-DbuHW0gF.css → index-Z4u1EVXA.css} +1 -1
- package/dist/assets/session-FqpMK7PV.js +24 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/app.tsx +82 -61
- package/src/components/dialog-command-palette.tsx +70 -0
- package/src/components/dialog-fork.tsx +1 -1
- package/src/components/dialog-select-file.tsx +1 -1
- package/src/components/prompt-input/submit.ts +1 -1
- package/src/components/titlebar.tsx +12 -1
- package/src/context/notification.tsx +2 -2
- package/src/pages/directory-layout.tsx +2 -2
- package/src/pages/home.tsx +104 -19
- package/src/pages/layout/sidebar-items.tsx +3 -3
- package/src/pages/layout/sidebar-workspace.tsx +1 -1
- package/src/pages/layout.tsx +174 -173
- package/src/pages/session/message-timeline.tsx +4 -4
- package/src/pages/session/use-session-commands.tsx +1 -1
- package/src/pages/session.tsx +1 -1
- package/dist/assets/home-BTCNns6Z.js +0 -1
- package/dist/assets/session-S93i-VnN.js +0 -24
|
@@ -101,7 +101,7 @@ const SessionRow = (props: {
|
|
|
101
101
|
cancelHoverPrefetch: () => void
|
|
102
102
|
}): JSX.Element => (
|
|
103
103
|
<A
|
|
104
|
-
href={`/${props.slug}
|
|
104
|
+
href={`/${props.slug}/${props.session.id}`}
|
|
105
105
|
class={`flex items-center justify-between gap-3 min-w-0 text-left w-full focus:outline-none transition-[padding] ${props.mobile ? "pr-7" : ""} group-hover/session:pr-7 group-focus-within/session:pr-7 group-active/session:pr-7 ${props.dense ? "py-0.5" : "py-1"}`}
|
|
106
106
|
onPointerEnter={props.scheduleHoverPrefetch}
|
|
107
107
|
onPointerLeave={props.cancelHoverPrefetch}
|
|
@@ -310,7 +310,7 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => {
|
|
|
310
310
|
onMessageSelect={(message) => {
|
|
311
311
|
if (!isActive()) {
|
|
312
312
|
layout.pendingMessage.set(`${base64Encode(props.session.directory)}/${props.session.id}`, message.id)
|
|
313
|
-
navigate(
|
|
313
|
+
navigate(`/${props.slug}/${props.session.id}`)
|
|
314
314
|
return
|
|
315
315
|
}
|
|
316
316
|
window.history.replaceState(null, "", `#message-${message.id}`)
|
|
@@ -360,7 +360,7 @@ export const NewSessionItem = (props: {
|
|
|
360
360
|
const tooltip = () => props.mobile || !props.sidebarExpanded()
|
|
361
361
|
const item = (
|
|
362
362
|
<A
|
|
363
|
-
href={`/${props.slug}
|
|
363
|
+
href={`/${props.slug}`}
|
|
364
364
|
end
|
|
365
365
|
class={`flex items-center justify-between gap-3 min-w-0 text-left w-full focus:outline-none ${props.dense ? "py-0.5" : "py-1"}`}
|
|
366
366
|
onClick={() => {
|
|
@@ -437,7 +437,7 @@ export const SortableWorkspace = (props: {
|
|
|
437
437
|
root={props.project.worktree}
|
|
438
438
|
setHoverSession={props.ctx.setHoverSession}
|
|
439
439
|
clearHoverProjectSoon={props.ctx.clearHoverProjectSoon}
|
|
440
|
-
navigateToNewSession={() => navigate(`/${slug()}
|
|
440
|
+
navigateToNewSession={() => navigate(`/${slug()}`)}
|
|
441
441
|
/>
|
|
442
442
|
</div>
|
|
443
443
|
</div>
|
package/src/pages/layout.tsx
CHANGED
|
@@ -49,7 +49,10 @@ import { useTheme, type ColorScheme } from "ikanban-ui/theme"
|
|
|
49
49
|
import { DialogSelectProvider } from "@/components/dialog-select-provider"
|
|
50
50
|
import { DialogSelectServer } from "@/components/dialog-select-server"
|
|
51
51
|
import { DialogSettings } from "@/components/dialog-settings"
|
|
52
|
+
import { DialogCommandPalette } from "@/components/dialog-command-palette"
|
|
53
|
+
import { DialogSelectFile } from "@/components/dialog-select-file"
|
|
52
54
|
import { useCommand, type CommandOption } from "@/context/command"
|
|
55
|
+
import { FileProvider } from "@/context/file"
|
|
53
56
|
import { ConstrainDragXAxis } from "@/utils/solid-dnd"
|
|
54
57
|
import { DialogSelectDirectory } from "@/components/dialog-select-directory"
|
|
55
58
|
import { DialogEditProject } from "@/components/dialog-edit-project"
|
|
@@ -121,9 +124,10 @@ export default function Layout(props: ParentProps) {
|
|
|
121
124
|
}
|
|
122
125
|
const colorSchemeLabel = (scheme: ColorScheme) => language.t(colorSchemeKey[scheme])
|
|
123
126
|
const currentDir = createMemo(() => decode64(params.dir) ?? "")
|
|
127
|
+
const hasDirectoryRoute = createMemo(() => !!params.dir)
|
|
124
128
|
|
|
125
129
|
const [state, setState] = createStore({
|
|
126
|
-
autoselect:
|
|
130
|
+
autoselect: false,
|
|
127
131
|
busyWorkspaces: {} as Record<string, boolean>,
|
|
128
132
|
hoverSession: undefined as string | undefined,
|
|
129
133
|
hoverProject: undefined as string | undefined,
|
|
@@ -196,15 +200,7 @@ export default function Layout(props: ParentProps) {
|
|
|
196
200
|
setHoverProject(undefined)
|
|
197
201
|
})
|
|
198
202
|
|
|
199
|
-
const autoselecting = createMemo(() =>
|
|
200
|
-
if (params.dir) return false
|
|
201
|
-
if (!state.autoselect) return false
|
|
202
|
-
if (!pageReady()) return true
|
|
203
|
-
if (!layoutReady()) return true
|
|
204
|
-
const list = layout.projects.list()
|
|
205
|
-
if (list.length > 0) return true
|
|
206
|
-
return !!server.projects.last()
|
|
207
|
-
})
|
|
203
|
+
const autoselecting = createMemo(() => false)
|
|
208
204
|
|
|
209
205
|
createEffect(() => {
|
|
210
206
|
if (!state.autoselect) return
|
|
@@ -325,7 +321,7 @@ export default function Layout(props: ParentProps) {
|
|
|
325
321
|
e.details.type === "permission.asked"
|
|
326
322
|
? language.t("notification.permission.description", { sessionTitle, projectName })
|
|
327
323
|
: language.t("notification.question.description", { sessionTitle, projectName })
|
|
328
|
-
const href = `/${base64Encode(directory)}
|
|
324
|
+
const href = `/${base64Encode(directory)}/${props.sessionID}`
|
|
329
325
|
|
|
330
326
|
const now = Date.now()
|
|
331
327
|
const lastAlerted = alertedAtBySession.get(sessionKey) ?? 0
|
|
@@ -426,34 +422,6 @@ export default function Layout(props: ParentProps) {
|
|
|
426
422
|
return projects.find((p) => p.worktree === root)
|
|
427
423
|
})
|
|
428
424
|
|
|
429
|
-
createEffect(
|
|
430
|
-
on(
|
|
431
|
-
() => ({ ready: pageReady(), layoutReady: layoutReady(), dir: params.dir, list: layout.projects.list() }),
|
|
432
|
-
(value) => {
|
|
433
|
-
if (!value.ready) return
|
|
434
|
-
if (!value.layoutReady) return
|
|
435
|
-
if (!state.autoselect) return
|
|
436
|
-
if (value.dir) return
|
|
437
|
-
|
|
438
|
-
const last = server.projects.last()
|
|
439
|
-
|
|
440
|
-
if (value.list.length === 0) {
|
|
441
|
-
if (!last) return
|
|
442
|
-
setState("autoselect", false)
|
|
443
|
-
openProject(last, false)
|
|
444
|
-
navigateToProject(last)
|
|
445
|
-
return
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const next = value.list.find((project) => project.worktree === last) ?? value.list[0]
|
|
449
|
-
if (!next) return
|
|
450
|
-
setState("autoselect", false)
|
|
451
|
-
openProject(next.worktree, false)
|
|
452
|
-
navigateToProject(next.worktree)
|
|
453
|
-
},
|
|
454
|
-
),
|
|
455
|
-
)
|
|
456
|
-
|
|
457
425
|
const workspaceName = (directory: string, projectId?: string, branch?: string) => {
|
|
458
426
|
const key = workspaceKey(directory)
|
|
459
427
|
const direct = store.workspaceName[key] ?? store.workspaceName[directory]
|
|
@@ -793,9 +761,9 @@ export default function Layout(props: ParentProps) {
|
|
|
793
761
|
)
|
|
794
762
|
if (session.id === params.id) {
|
|
795
763
|
if (nextSession) {
|
|
796
|
-
navigate(`/${params.dir}
|
|
764
|
+
navigate(`/${params.dir}/${nextSession.id}`)
|
|
797
765
|
} else {
|
|
798
|
-
navigate(`/${params.dir}
|
|
766
|
+
navigate(`/${params.dir}`)
|
|
799
767
|
}
|
|
800
768
|
}
|
|
801
769
|
}
|
|
@@ -809,6 +777,15 @@ export default function Layout(props: ParentProps) {
|
|
|
809
777
|
keybind: "mod+b",
|
|
810
778
|
onSelect: () => layout.sidebar.toggle(),
|
|
811
779
|
},
|
|
780
|
+
{
|
|
781
|
+
id: "file.open",
|
|
782
|
+
title: language.t("command.file.open"),
|
|
783
|
+
description: params.dir ? language.t("palette.search.placeholder") : language.t("command.project.open"),
|
|
784
|
+
category: language.t("command.category.file"),
|
|
785
|
+
keybind: "mod+p",
|
|
786
|
+
slash: "open",
|
|
787
|
+
onSelect: openGlobalFilePicker,
|
|
788
|
+
},
|
|
812
789
|
{
|
|
813
790
|
id: "project.open",
|
|
814
791
|
title: language.t("command.project.open"),
|
|
@@ -1059,7 +1036,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1059
1036
|
|
|
1060
1037
|
function navigateToSession(session: Session | undefined) {
|
|
1061
1038
|
if (!session) return
|
|
1062
|
-
navigateWithSidebarReset(`/${base64Encode(session.directory)}
|
|
1039
|
+
navigateWithSidebarReset(`/${base64Encode(session.directory)}/${session.id}`)
|
|
1063
1040
|
}
|
|
1064
1041
|
|
|
1065
1042
|
function openProject(directory: string, navigate = true) {
|
|
@@ -1124,7 +1101,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1124
1101
|
return
|
|
1125
1102
|
}
|
|
1126
1103
|
|
|
1127
|
-
navigateWithSidebarReset(`/${base64Encode(next.worktree)}
|
|
1104
|
+
navigateWithSidebarReset(`/${base64Encode(next.worktree)}`)
|
|
1128
1105
|
layout.projects.close(directory)
|
|
1129
1106
|
queueMicrotask(() => {
|
|
1130
1107
|
void navigateToProject(next.worktree)
|
|
@@ -1169,6 +1146,19 @@ export default function Layout(props: ParentProps) {
|
|
|
1169
1146
|
}
|
|
1170
1147
|
}
|
|
1171
1148
|
|
|
1149
|
+
function openGlobalFilePicker() {
|
|
1150
|
+
if (!params.dir) {
|
|
1151
|
+
dialog.show(() => <DialogCommandPalette />)
|
|
1152
|
+
return
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
dialog.show(() => (
|
|
1156
|
+
<FileProvider>
|
|
1157
|
+
<DialogSelectFile />
|
|
1158
|
+
</FileProvider>
|
|
1159
|
+
))
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1172
1162
|
const deleteWorkspace = async (root: string, directory: string, leaveDeletedWorkspace = false) => {
|
|
1173
1163
|
if (directory === root) return
|
|
1174
1164
|
|
|
@@ -1177,7 +1167,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1177
1167
|
const deletedKey = workspaceKey(directory)
|
|
1178
1168
|
const shouldLeave = leaveDeletedWorkspace || (!!params.dir && currentKey === deletedKey)
|
|
1179
1169
|
if (!leaveDeletedWorkspace && shouldLeave) {
|
|
1180
|
-
navigateWithSidebarReset(`/${base64Encode(root)}
|
|
1170
|
+
navigateWithSidebarReset(`/${base64Encode(root)}`)
|
|
1181
1171
|
}
|
|
1182
1172
|
|
|
1183
1173
|
setBusy(directory, true)
|
|
@@ -1225,7 +1215,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1225
1215
|
const valid = dirs.some((item) => workspaceKey(item) === nextKey)
|
|
1226
1216
|
|
|
1227
1217
|
if (params.dir && projectRoot(nextCurrent) === root && !valid) {
|
|
1228
|
-
navigateWithSidebarReset(`/${base64Encode(root)}
|
|
1218
|
+
navigateWithSidebarReset(`/${base64Encode(root)}`)
|
|
1229
1219
|
}
|
|
1230
1220
|
}
|
|
1231
1221
|
|
|
@@ -1294,7 +1284,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1294
1284
|
{
|
|
1295
1285
|
label: language.t("command.session.new"),
|
|
1296
1286
|
onClick: () => {
|
|
1297
|
-
const href = `/${base64Encode(directory)}
|
|
1287
|
+
const href = `/${base64Encode(directory)}`
|
|
1298
1288
|
navigate(href)
|
|
1299
1289
|
layout.mobileSidebar.hide()
|
|
1300
1290
|
},
|
|
@@ -1330,7 +1320,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1330
1320
|
const handleDelete = () => {
|
|
1331
1321
|
const leaveDeletedWorkspace = !!params.dir && workspaceKey(currentDir()) === workspaceKey(props.directory)
|
|
1332
1322
|
if (leaveDeletedWorkspace) {
|
|
1333
|
-
navigateWithSidebarReset(`/${base64Encode(props.root)}
|
|
1323
|
+
navigateWithSidebarReset(`/${base64Encode(props.root)}`)
|
|
1334
1324
|
}
|
|
1335
1325
|
dialog.close()
|
|
1336
1326
|
void deleteWorkspace(props.root, props.directory, leaveDeletedWorkspace)
|
|
@@ -1481,6 +1471,10 @@ export default function Layout(props: ParentProps) {
|
|
|
1481
1471
|
)
|
|
1482
1472
|
|
|
1483
1473
|
createEffect(() => {
|
|
1474
|
+
if (!hasDirectoryRoute()) {
|
|
1475
|
+
document.documentElement.style.setProperty("--dialog-left-margin", "0px")
|
|
1476
|
+
return
|
|
1477
|
+
}
|
|
1484
1478
|
const sidebarWidth = layout.sidebar.opened() ? layout.sidebar.width() : 48
|
|
1485
1479
|
document.documentElement.style.setProperty("--dialog-left-margin", `${sidebarWidth}px`)
|
|
1486
1480
|
})
|
|
@@ -1628,7 +1622,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1628
1622
|
})
|
|
1629
1623
|
|
|
1630
1624
|
globalSync.child(created.directory)
|
|
1631
|
-
navigateWithSidebarReset(`/${base64Encode(created.directory)}
|
|
1625
|
+
navigateWithSidebarReset(`/${base64Encode(created.directory)}`)
|
|
1632
1626
|
}
|
|
1633
1627
|
|
|
1634
1628
|
const workspaceSidebarCtx: WorkspaceSidebarContext = {
|
|
@@ -1821,7 +1815,7 @@ export default function Layout(props: ParentProps) {
|
|
|
1821
1815
|
size="large"
|
|
1822
1816
|
icon="plus-small"
|
|
1823
1817
|
class="w-full"
|
|
1824
|
-
onClick={() => navigateWithSidebarReset(`/${base64Encode(p().worktree)}
|
|
1818
|
+
onClick={() => navigateWithSidebarReset(`/${base64Encode(p().worktree)}`)}
|
|
1825
1819
|
>
|
|
1826
1820
|
{language.t("command.session.new")}
|
|
1827
1821
|
</Button>
|
|
@@ -1923,136 +1917,143 @@ export default function Layout(props: ParentProps) {
|
|
|
1923
1917
|
|
|
1924
1918
|
return (
|
|
1925
1919
|
<div class="relative bg-background-base flex-1 min-h-0 flex flex-col select-none [&_input]:select-text [&_textarea]:select-text [&_[contenteditable]]:select-text">
|
|
1926
|
-
<
|
|
1920
|
+
<Show when={hasDirectoryRoute()}>
|
|
1921
|
+
<Titlebar />
|
|
1922
|
+
</Show>
|
|
1927
1923
|
<div class="flex-1 min-h-0 flex">
|
|
1928
|
-
<
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
{(
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
{(worktree) => (
|
|
1987
|
-
<div class="absolute inset-y-0 left-16 z-50 flex" onMouseEnter={aim.reset}>
|
|
1988
|
-
<SidebarPanel project={hoverProjectData()} />
|
|
1924
|
+
<Show when={hasDirectoryRoute()}>
|
|
1925
|
+
<>
|
|
1926
|
+
<nav
|
|
1927
|
+
aria-label={language.t("sidebar.nav.projectsAndSessions")}
|
|
1928
|
+
data-component="sidebar-nav-desktop"
|
|
1929
|
+
classList={{
|
|
1930
|
+
"hidden xl:block": true,
|
|
1931
|
+
"relative shrink-0": true,
|
|
1932
|
+
}}
|
|
1933
|
+
style={{ width: layout.sidebar.opened() ? `${Math.max(layout.sidebar.width(), 244)}px` : "64px" }}
|
|
1934
|
+
ref={(el) => {
|
|
1935
|
+
setState("nav", el)
|
|
1936
|
+
}}
|
|
1937
|
+
onMouseEnter={() => {
|
|
1938
|
+
if (navLeave.current === undefined) return
|
|
1939
|
+
clearTimeout(navLeave.current)
|
|
1940
|
+
navLeave.current = undefined
|
|
1941
|
+
}}
|
|
1942
|
+
onMouseLeave={() => {
|
|
1943
|
+
aim.reset()
|
|
1944
|
+
if (!sidebarHovering()) return
|
|
1945
|
+
|
|
1946
|
+
if (navLeave.current !== undefined) clearTimeout(navLeave.current)
|
|
1947
|
+
navLeave.current = window.setTimeout(() => {
|
|
1948
|
+
navLeave.current = undefined
|
|
1949
|
+
setHoverProject(undefined)
|
|
1950
|
+
setState("hoverSession", undefined)
|
|
1951
|
+
}, 300)
|
|
1952
|
+
}}
|
|
1953
|
+
>
|
|
1954
|
+
<div class="@container w-full h-full contain-strict">
|
|
1955
|
+
<SidebarContent
|
|
1956
|
+
opened={() => layout.sidebar.opened()}
|
|
1957
|
+
aimMove={aim.move}
|
|
1958
|
+
projects={() => layout.projects.list()}
|
|
1959
|
+
renderProject={(project) => (
|
|
1960
|
+
<SortableProject ctx={projectSidebarCtx} project={project} sortNow={sortNow} />
|
|
1961
|
+
)}
|
|
1962
|
+
handleDragStart={handleDragStart}
|
|
1963
|
+
handleDragEnd={handleDragEnd}
|
|
1964
|
+
handleDragOver={handleDragOver}
|
|
1965
|
+
openProjectLabel={language.t("command.project.open")}
|
|
1966
|
+
openProjectKeybind={() => command.keybind("project.open")}
|
|
1967
|
+
onOpenProject={chooseProject}
|
|
1968
|
+
renderProjectOverlay={() => (
|
|
1969
|
+
<ProjectDragOverlay projects={() => layout.projects.list()} activeProject={() => store.activeProject} />
|
|
1970
|
+
)}
|
|
1971
|
+
settingsLabel={() => language.t("sidebar.settings")}
|
|
1972
|
+
settingsKeybind={() => command.keybind("settings.open")}
|
|
1973
|
+
onOpenSettings={openSettings}
|
|
1974
|
+
helpLabel={() => language.t("sidebar.help")}
|
|
1975
|
+
onOpenHelp={() => platform.openLink("https://github.com/isomoes/ikanban/issues")}
|
|
1976
|
+
renderPanel={() => (
|
|
1977
|
+
<Show when={currentProject()} keyed>
|
|
1978
|
+
{(project) => <SidebarPanel project={project} />}
|
|
1979
|
+
</Show>
|
|
1980
|
+
)}
|
|
1981
|
+
/>
|
|
1989
1982
|
</div>
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
1983
|
+
<Show when={!layout.sidebar.opened() ? hoverProjectData()?.worktree : undefined} keyed>
|
|
1984
|
+
{(worktree) => (
|
|
1985
|
+
<div class="absolute inset-y-0 left-16 z-50 flex" onMouseEnter={aim.reset}>
|
|
1986
|
+
<SidebarPanel project={hoverProjectData()} />
|
|
1987
|
+
</div>
|
|
1988
|
+
)}
|
|
1989
|
+
</Show>
|
|
1990
|
+
<Show when={layout.sidebar.opened()}>
|
|
1991
|
+
<ResizeHandle
|
|
1992
|
+
direction="horizontal"
|
|
1993
|
+
size={layout.sidebar.width()}
|
|
1994
|
+
min={244}
|
|
1995
|
+
max={typeof window === "undefined" ? 1000 : window.innerWidth * 0.3 + 64}
|
|
1996
|
+
collapseThreshold={244}
|
|
1997
|
+
onResize={layout.sidebar.resize}
|
|
1998
|
+
onCollapse={layout.sidebar.close}
|
|
1999
|
+
/>
|
|
2000
|
+
</Show>
|
|
2001
|
+
</nav>
|
|
2002
|
+
<div class="xl:hidden">
|
|
2003
|
+
<div
|
|
2004
|
+
classList={{
|
|
2005
|
+
"fixed inset-x-0 top-10 bottom-0 z-40 transition-opacity duration-200": true,
|
|
2006
|
+
"opacity-100 pointer-events-auto": layout.mobileSidebar.opened(),
|
|
2007
|
+
"opacity-0 pointer-events-none": !layout.mobileSidebar.opened(),
|
|
2008
|
+
}}
|
|
2009
|
+
onClick={(e) => {
|
|
2010
|
+
if (e.target === e.currentTarget) layout.mobileSidebar.hide()
|
|
2011
|
+
}}
|
|
2012
|
+
/>
|
|
2013
|
+
<nav
|
|
2014
|
+
aria-label={language.t("sidebar.nav.projectsAndSessions")}
|
|
2015
|
+
data-component="sidebar-nav-mobile"
|
|
2016
|
+
classList={{
|
|
2017
|
+
"@container fixed top-10 bottom-0 left-0 z-50 w-72 bg-background-base transition-transform duration-200 ease-out": true,
|
|
2018
|
+
"translate-x-0": layout.mobileSidebar.opened(),
|
|
2019
|
+
"-translate-x-full": !layout.mobileSidebar.opened(),
|
|
2020
|
+
}}
|
|
2021
|
+
onClick={(e) => e.stopPropagation()}
|
|
2022
|
+
>
|
|
2023
|
+
<SidebarContent
|
|
2024
|
+
mobile
|
|
2025
|
+
opened={() => layout.sidebar.opened()}
|
|
2026
|
+
aimMove={aim.move}
|
|
2027
|
+
projects={() => layout.projects.list()}
|
|
2028
|
+
renderProject={(project) => (
|
|
2029
|
+
<SortableProject ctx={projectSidebarCtx} project={project} sortNow={sortNow} mobile />
|
|
2030
|
+
)}
|
|
2031
|
+
handleDragStart={handleDragStart}
|
|
2032
|
+
handleDragEnd={handleDragEnd}
|
|
2033
|
+
handleDragOver={handleDragOver}
|
|
2034
|
+
openProjectLabel={language.t("command.project.open")}
|
|
2035
|
+
openProjectKeybind={() => command.keybind("project.open")}
|
|
2036
|
+
onOpenProject={chooseProject}
|
|
2037
|
+
renderProjectOverlay={() => (
|
|
2038
|
+
<ProjectDragOverlay projects={() => layout.projects.list()} activeProject={() => store.activeProject} />
|
|
2039
|
+
)}
|
|
2040
|
+
settingsLabel={() => language.t("sidebar.settings")}
|
|
2041
|
+
settingsKeybind={() => command.keybind("settings.open")}
|
|
2042
|
+
onOpenSettings={openSettings}
|
|
2043
|
+
helpLabel={() => language.t("sidebar.help")}
|
|
2044
|
+
onOpenHelp={() => platform.openLink("https://github.com/isomoes/ikanban/issues")}
|
|
2045
|
+
renderPanel={() => <SidebarPanel project={currentProject()} mobile />}
|
|
2046
|
+
/>
|
|
2047
|
+
</nav>
|
|
2048
|
+
</div>
|
|
2049
|
+
</>
|
|
2050
|
+
</Show>
|
|
2051
2051
|
|
|
2052
2052
|
<main
|
|
2053
2053
|
classList={{
|
|
2054
2054
|
"size-full overflow-x-hidden flex flex-col items-start contain-strict border-t border-border-weak-base": true,
|
|
2055
|
-
"xl:border-l xl:rounded-tl-[12px]": !layout.sidebar.opened(),
|
|
2055
|
+
"xl:border-l xl:rounded-tl-[12px]": hasDirectoryRoute() && !layout.sidebar.opened(),
|
|
2056
|
+
"border-t-0": !hasDirectoryRoute(),
|
|
2056
2057
|
}}
|
|
2057
2058
|
>
|
|
2058
2059
|
<Show when={!autoselecting()} fallback={<div class="size-full" />}>
|
|
@@ -346,14 +346,14 @@ export function MessageTimeline(props: {
|
|
|
346
346
|
const navigateAfterSessionRemoval = (sessionID: string, parentID?: string, nextSessionID?: string) => {
|
|
347
347
|
if (params.id !== sessionID) return
|
|
348
348
|
if (parentID) {
|
|
349
|
-
navigate(`/${params.dir}
|
|
349
|
+
navigate(`/${params.dir}/${parentID}`)
|
|
350
350
|
return
|
|
351
351
|
}
|
|
352
352
|
if (nextSessionID) {
|
|
353
|
-
navigate(`/${params.dir}
|
|
353
|
+
navigate(`/${params.dir}/${nextSessionID}`)
|
|
354
354
|
return
|
|
355
355
|
}
|
|
356
|
-
navigate(`/${params.dir}
|
|
356
|
+
navigate(`/${params.dir}`)
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
const archiveSession = async (sessionID: string) => {
|
|
@@ -446,7 +446,7 @@ export function MessageTimeline(props: {
|
|
|
446
446
|
const navigateParent = () => {
|
|
447
447
|
const id = parentID()
|
|
448
448
|
if (!id) return
|
|
449
|
-
navigate(`/${params.dir}
|
|
449
|
+
navigate(`/${params.dir}/${id}`)
|
|
450
450
|
}
|
|
451
451
|
|
|
452
452
|
function DialogDeleteSession(props: { sessionID: string }) {
|
|
@@ -194,7 +194,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
|
|
|
194
194
|
title: language.t("command.session.new"),
|
|
195
195
|
keybind: "mod+shift+s",
|
|
196
196
|
slash: "new",
|
|
197
|
-
onSelect: () => navigate(`/${params.dir}
|
|
197
|
+
onSelect: () => navigate(`/${params.dir}`),
|
|
198
198
|
}),
|
|
199
199
|
]);
|
|
200
200
|
|
package/src/pages/session.tsx
CHANGED
|
@@ -1319,7 +1319,7 @@ export default function Page() {
|
|
|
1319
1319
|
if (!target) return
|
|
1320
1320
|
if (target === sdk.directory) return
|
|
1321
1321
|
layout.projects.open(target)
|
|
1322
|
-
navigate(`/${base64Encode(target)}
|
|
1322
|
+
navigate(`/${base64Encode(target)}`)
|
|
1323
1323
|
}}
|
|
1324
1324
|
/>
|
|
1325
1325
|
</Match>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as K,a as N,b as q,c as H,d as T,e as V,f as J,g as Q,h as P,s as U,i as W,j as t,k as s,L as X,B as z,l as I,m as Y,n as Z,D as ee,M as A,I as L,S as R,o as O,p as te,t as c,F as re,q as se,r as le,v as ie}from"./index-n2BMSLCz.js";var ne=c("<div>"),oe=c('<div class="mt-6 flex w-full flex-col gap-6"><section class="flex flex-col gap-4"><div class="grid gap-3 lg:grid-cols-2">'),ae=c('<div class="mt-6 rounded-2xl border border-dashed border-border-weak bg-background-base/60 px-6 py-10"><div class="mx-auto flex max-w-md flex-col items-center gap-3 text-center"><div class="flex size-12 items-center justify-center rounded-2xl border border-border-weak bg-background-base/80"></div><div class="flex flex-col gap-1 items-center justify-center"><div class="text-14-medium text-text-strong"></div><div class="text-12-regular text-text-weak">'),ce=c('<div class="mx-auto w-full max-w-7xl px-4 py-6 md:px-6 md:py-8"><div class="flex flex-col gap-4 md:flex-row md:items-start md:justify-between"><div class=min-w-0><div class="flex items-center gap-3"><div class="flex size-10 items-center justify-center rounded-2xl border border-border-weak bg-background-base/80"></div><div><div class="text-18-medium text-text-strong"></div><div class="mt-0.5 text-12-regular text-text-weak"></div></div></div></div><div class="flex items-center gap-2 self-start md:justify-end">'),de=c('<div class="rounded-xl border border-dashed border-border-weak px-3 py-8 text-center text-12-regular text-text-weak">'),ue=c('<section class="rounded-2xl border border-border-weak bg-background-base/80 p-3 md:p-4 min-h-72"><div class="flex items-center justify-between gap-3"><div class="flex items-center gap-2 min-w-0"><div></div><div class="text-14-medium text-text-strong"></div></div><div class="text-12-mono text-text-weak"></div></div><div class="mt-3 flex flex-col gap-2">'),me=c('<span class="min-w-0 flex-1 truncate text-12-regular text-text-weak">'),ge=c('<div class="flex shrink-0 items-center gap-2 text-12-regular text-text-weak"><span>'),fe=c('<div class="overflow-hidden rounded-xl border border-border-weak bg-background-base/70 hover:border-border-strong"><div class="flex items-start justify-between gap-3 px-3 pt-3"><div class="min-w-0 flex-1 pt-1"><div class="truncate text-14-medium leading-tight text-text-strong">');function xe(){const l=K(),j=N(),x=q(),h=H(),v=T(),b=V(),g=J(),i=Q(),C=P(()=>l.data.project.slice().sort((e,r)=>(r.time.updated??r.time.created)-(e.time.updated??e.time.created)).slice(0,5)),n=P(()=>{const e=Date.now(),r={progress:[],idle:[]};for(const a of C()){const[d]=l.child(a.worktree),u=U(d,e);for(const f of u){const y=d.session_status[f.id],B=f.time.updated??f.time.created,_={session:f,projectDirectory:a.worktree,updatedAt:B};if(y?.type==="busy"||y?.type==="retry"){r.progress.push(_);continue}r.idle.push(_)}}for(const a of Object.keys(r))r[a].sort((d,u)=>u.updatedAt-d.updatedAt);return r});W(()=>{for(const e of C())l.child(e.worktree)});const w=P(()=>{const e=g.healthy();return e===!0?"bg-icon-success-base":e===!1?"bg-icon-critical-base":"bg-border-weak-base"});function $(e){j.projects.open(e),g.projects.touch(e),v(`/${O(e)}/session`)}function S(e,r){j.projects.open(e),g.projects.touch(e),v(`/${O(e)}/session/${r}`)}async function D(e,r){const[,a]=l.child(e,{bootstrap:!1});await b.client.session.update({sessionID:r,time:{archived:Date.now()}}),a("session",d=>d.filter(u=>u.id!==r))}async function o(){function e(r){if(Array.isArray(r))for(const a of r)$(a);else r&&$(r)}if(x.openDirectoryPickerDialog&&g.isLocal()){const r=await x.openDirectoryPickerDialog?.({title:i.t("command.project.open"),multiple:!0});e(r)}else h.show(()=>s(te,{multiple:!0,onSelect:e}),()=>e(null))}return(()=>{var e=ce(),r=e.firstChild,a=r.firstChild,d=a.firstChild,u=d.firstChild,f=u.nextSibling,y=f.firstChild,B=y.nextSibling,_=a.nextSibling;return t(u,s(X,{class:"w-6 opacity-90"})),t(y,()=>i.t("home.sessionBoard")),t(B,()=>i.t("home.sessionBoard.description")),t(_,s(z,{icon:"folder-add-left",size:"normal",class:"pl-2 pr-3",onClick:o,get children(){return i.t("command.project.open")}}),null),t(_,s(z,{size:"normal",variant:"ghost",class:"pr-3 text-13-regular text-text-weak",onClick:()=>h.show(()=>s(ee,{})),get children(){return[(()=>{var m=ne();return I(p=>Y(m,{"size-2 rounded-full":!0,[w()]:!0},p)),m})(),Z(()=>g.name)]}}),null),t(e,s(R,{get children(){return[s(A,{get when(){return l.data.project.length>0},get children(){var m=oe(),p=m.firstChild,k=p.firstChild;return t(k,s(E,{get title(){return i.t("home.sessionBoard.progress")},icon:"brain",tone:"progress",get cards(){return n().progress},onOpen:S,onArchive:D,get empty(){return i.t("home.sessionBoard.emptyProgress")}}),null),t(k,s(E,{get title(){return i.t("home.sessionBoard.idle")},icon:"dash",tone:"idle",get cards(){return n().idle},onOpen:S,onArchive:D,get empty(){return i.t("home.sessionBoard.emptyIdle")}}),null),m}}),s(A,{when:!0,get children(){var m=ae(),p=m.firstChild,k=p.firstChild,F=k.nextSibling,M=F.firstChild,G=M.nextSibling;return t(k,s(L,{name:"folder-add-left",size:"large"})),t(M,()=>i.t("home.empty.title")),t(G,()=>i.t("home.empty.description")),t(p,s(z,{class:"mt-1 px-3",onClick:o,get children(){return i.t("command.project.open")}}),null),m}})]}}),null),e})()}function E(l){const j=()=>l.tone==="progress"?"bg-emerald-500/12 text-emerald-300 border-emerald-500/20":"bg-sky-500/12 text-sky-300 border-sky-500/20";return(()=>{var x=ue(),h=x.firstChild,v=h.firstChild,b=v.firstChild,g=b.nextSibling,i=v.nextSibling,C=h.nextSibling;return t(b,s(L,{get name(){return l.icon},size:"small"})),t(g,()=>l.title),t(i,()=>l.cards.length),t(C,s(R,{get children(){return[s(A,{get when(){return l.cards.length>0},get children(){return s(re,{get each(){return l.cards},children:n=>(()=>{var w=fe(),$=w.firstChild,S=$.firstChild,D=S.firstChild;return t(D,()=>n.session.title),t($,s(se,{icon:"archive",variant:"ghost",class:"size-7 rounded-md","aria-label":"Archive session",onClick:o=>{o.preventDefault(),o.stopPropagation(),l.onArchive(n.projectDirectory,n.session.id)}}),null),t(w,s(z,{variant:"ghost",class:"flex h-auto w-full min-w-0 items-center justify-between gap-3 rounded-none border-0 bg-transparent px-3 pb-3 pt-2 text-left",onClick:()=>l.onOpen(n.projectDirectory,n.session.id),get children(){return[(()=>{var o=me();return t(o,()=>n.projectDirectory.replace(/^.*?([^/\\]+(?:[/\\][^/\\]+)?)$/,"$1")),o})(),(()=>{var o=ge(),e=o.firstChild;return t(e,()=>le.fromMillis(n.updatedAt).toRelative()),t(o,s(L,{name:"arrow-right",size:"small",class:"text-icon-weak shrink-0"}),null),o})()]}}),null),w})()})}}),s(A,{when:!0,get children(){var n=de();return t(n,()=>l.empty),n}})]}})),I(()=>ie(b,`size-7 rounded-full border flex items-center justify-center ${j()}`)),x})()}export{xe as default};
|