mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-08 03:53:22 +00:00
fix(app): align workspace interactions and styling with designs
This commit is contained in:
parent
c40aecbdbe
commit
a597364516
7 changed files with 154 additions and 113 deletions
|
|
@ -104,7 +104,9 @@ test("selects local, new, and existing workspaces from the ready-ish start menu"
|
|||
await trigger.click()
|
||||
const newWorkspace = page.getByRole("menuitem", { name: /New workspace/ })
|
||||
await expect(newWorkspace).toBeVisible()
|
||||
await expect(page.getByRole("menuitem", { name: /Workspace/ })).toBeVisible()
|
||||
const workspaceTrigger = page.getByRole("menuitem", { name: /Workspace/ })
|
||||
await expect(workspaceTrigger).toBeVisible()
|
||||
await workspaceTrigger.hover()
|
||||
await expect(page.getByRole("menuitem", { name: "View all" })).toBeVisible()
|
||||
|
||||
await newWorkspace.click()
|
||||
|
|
@ -133,7 +135,7 @@ test("searches long workspace lists within the available viewport", async ({ pag
|
|||
|
||||
await page.goto(`/new-session?draftId=${draftID}`)
|
||||
await expectAppVisible(page.locator('[data-component="prompt-input"]'))
|
||||
await page.getByRole("button", { name: /^local$/i }).click()
|
||||
await page.getByRole("button", { name: /local|new workspace/i }).click()
|
||||
await page.getByRole("menuitem", { name: /Workspace/ }).focus()
|
||||
await page.keyboard.press("ArrowRight")
|
||||
|
||||
|
|
@ -203,7 +205,9 @@ test("lists and manually deletes workspaces from settings", async ({ page }) =>
|
|||
|
||||
await page.goto(`/new-session?draftId=${draftID}`)
|
||||
await expectAppVisible(page.locator('[data-component="prompt-input"]'))
|
||||
await page.getByRole("button", { name: /^local$/i }).click()
|
||||
await page.getByRole("button", { name: /local|new workspace/i }).click()
|
||||
const workspacesTrigger = page.getByRole("menuitem", { name: /Workspace/ })
|
||||
if (await workspacesTrigger.isVisible()) await workspacesTrigger.hover()
|
||||
await page.getByRole("menuitem", { name: "View all" }).click()
|
||||
|
||||
const settings = page.locator(".settings-v2-dialog")
|
||||
|
|
@ -215,7 +219,8 @@ test("lists and manually deletes workspaces from settings", async ({ page }) =>
|
|||
const firstSessionInventory = sessionListRequests
|
||||
await page.keyboard.press("Escape")
|
||||
await expect(settings).toHaveCount(0)
|
||||
await page.getByRole("button", { name: /^local$/i }).click()
|
||||
await page.getByRole("button", { name: /local|new workspace/i }).click()
|
||||
if (await workspacesTrigger.isVisible()) await workspacesTrigger.hover()
|
||||
await page.getByRole("menuitem", { name: "View all" }).click()
|
||||
await expect(settings.getByText("Workspace settings session", { exact: true })).toBeVisible()
|
||||
expect(sessionListRequests).toBeGreaterThan(firstSessionInventory)
|
||||
|
|
@ -273,6 +278,8 @@ test("blocks deletion of the currently active workspace", async ({ page }) => {
|
|||
|
||||
await page.goto(`/new-session?draftId=${draftID}`)
|
||||
await page.getByRole("button", { name: /feature/ }).click()
|
||||
const workspacesTrigger = page.getByRole("menuitem", { name: /Workspace/ })
|
||||
if (await workspacesTrigger.isVisible()) await workspacesTrigger.hover()
|
||||
await page.getByRole("menuitem", { name: "View all" }).click()
|
||||
const settings = page.locator(".settings-v2-dialog")
|
||||
await settings.getByRole("button", { name: 'Delete workspace "feature"?' }).click()
|
||||
|
|
@ -313,7 +320,9 @@ test("wraps the workspace toolbar for long project filters on mobile", async ({
|
|||
await page.goto(`/new-session?draftId=${draftID}`)
|
||||
const dismissTabs = page.getByRole("button", { name: "Dismiss Tabs information" })
|
||||
if (await dismissTabs.isVisible()) await dismissTabs.click()
|
||||
await page.getByRole("button", { name: /^local$/i }).click()
|
||||
await page.getByRole("button", { name: /local|new workspace/i }).click()
|
||||
const workspacesTrigger = page.getByRole("menuitem", { name: /Workspace/ })
|
||||
if (await workspacesTrigger.isVisible()) await workspacesTrigger.hover()
|
||||
await page.getByRole("menuitem", { name: "View all" }).click()
|
||||
const settings = page.locator(".settings-v2-dialog")
|
||||
await expect(settings.getByRole("button", { name: "All projects" })).toBeVisible()
|
||||
|
|
@ -389,7 +398,9 @@ test("bulk deletion snapshots inventory and skips dirty or unknown workspaces",
|
|||
|
||||
await page.goto(`/new-session?draftId=${draftID}`)
|
||||
await transport.waitForConnection()
|
||||
await page.getByRole("button", { name: /^local$/i }).click()
|
||||
await page.getByRole("button", { name: /local|new workspace/i }).click()
|
||||
const workspacesTrigger = page.getByRole("menuitem", { name: /Workspace/ })
|
||||
if (await workspacesTrigger.isVisible()) await workspacesTrigger.hover()
|
||||
await page.getByRole("menuitem", { name: "View all" }).click()
|
||||
const settings = page.locator(".settings-v2-dialog")
|
||||
await settings.getByRole("button", { name: "More options" }).click()
|
||||
|
|
|
|||
|
|
@ -129,7 +129,17 @@ export function PromptWorkspaceSelector(props: {
|
|||
</Show>
|
||||
</MenuV2.Item>
|
||||
</MenuV2.Group>
|
||||
<Show when={props.workspaces.length > 0}>
|
||||
<Show
|
||||
when={props.workspaces.length > 0}
|
||||
fallback={
|
||||
<>
|
||||
<MenuV2.Separator class="h-[0.5px]" />
|
||||
<MenuV2.Item onSelect={() => (pending = { type: "viewAll" })}>
|
||||
<span class="min-w-0 flex-1 truncate">{language.t("common.viewAll")}</span>
|
||||
</MenuV2.Item>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<MenuV2.Separator class="h-[0.5px]" />
|
||||
<MenuV2.Sub
|
||||
gutter={0}
|
||||
|
|
@ -199,14 +209,14 @@ export function PromptWorkspaceSelector(props: {
|
|||
</MenuV2.Item>
|
||||
)}
|
||||
</For>
|
||||
<MenuV2.Separator class="h-[0.5px]" />
|
||||
<MenuV2.Item onSelect={() => (pending = { type: "viewAll" })}>
|
||||
<span class="min-w-0 flex-1 truncate">{language.t("common.viewAll")}</span>
|
||||
</MenuV2.Item>
|
||||
</MenuV2.SubContent>
|
||||
</MenuV2.Portal>
|
||||
</MenuV2.Sub>
|
||||
</Show>
|
||||
<MenuV2.Separator class="h-[0.5px]" />
|
||||
<MenuV2.Item onSelect={() => (pending = { type: "viewAll" })}>
|
||||
<span class="min-w-0 flex-1 truncate">{language.t("common.viewAll")}</span>
|
||||
</MenuV2.Item>
|
||||
</MenuV2.Content>
|
||||
</MenuV2.Portal>
|
||||
</MenuV2>
|
||||
|
|
@ -225,12 +235,12 @@ export function PromptWorkspaceSelector(props: {
|
|||
</div>
|
||||
</Show>
|
||||
</TooltipV2>
|
||||
<PromptGitStatus branch={props.branch} from={selected() === "create"} connected={selected() === "create"} />
|
||||
<PromptGitStatus branch={props.branch} from={selected() === "create"} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function PromptGitStatus(props: { branch?: string; noGit?: boolean; from?: boolean; connected?: boolean }) {
|
||||
export function PromptGitStatus(props: { branch?: string; noGit?: boolean; from?: boolean }) {
|
||||
const language = useLanguage()
|
||||
const label = () => {
|
||||
if (props.noGit) return language.t("session.new.git.none")
|
||||
|
|
@ -239,32 +249,30 @@ export function PromptGitStatus(props: { branch?: string; noGit?: boolean; from?
|
|||
return props.branch
|
||||
}
|
||||
|
||||
const icon = () => {
|
||||
if (props.noGit) return "monitor"
|
||||
if (props.from) return "branch-out"
|
||||
return "branch"
|
||||
}
|
||||
|
||||
return (
|
||||
<Show when={label()}>
|
||||
{(value) => (
|
||||
<>
|
||||
<Show when={!props.connected}>
|
||||
<span class="hidden select-none opacity-50 sm:inline mx-1">/</span>
|
||||
</Show>
|
||||
<TooltipV2
|
||||
placement="top"
|
||||
value={value()}
|
||||
class="min-w-0 max-w-[220px]"
|
||||
contentClass="max-w-[calc(100vw-32px)] break-all"
|
||||
>
|
||||
<div
|
||||
class="flex h-6 min-w-0 max-w-[220px] items-center gap-1.5 px-1.5 text-[13px] font-[440] leading-5 tracking-[-0.04px]"
|
||||
classList={{ "ml-0.5": props.connected }}
|
||||
>
|
||||
<Icon
|
||||
name={props.noGit ? "monitor" : "branch"}
|
||||
size="small"
|
||||
class="shrink-0 text-v2-icon-icon-muted"
|
||||
/>
|
||||
<span class="min-w-0 truncate">{value()}</span>
|
||||
</div>
|
||||
</TooltipV2>
|
||||
</>
|
||||
<TooltipV2
|
||||
placement="top"
|
||||
value={value()}
|
||||
class="min-w-0 max-w-[220px]"
|
||||
contentClass="max-w-[calc(100vw-32px)] break-all"
|
||||
>
|
||||
<div class="flex h-6 min-w-0 max-w-[220px] items-center gap-1.5 rounded-full bg-v2-background-bg-layer-02 px-2.5 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-faint">
|
||||
<Icon
|
||||
name={icon()}
|
||||
size="small"
|
||||
class="shrink-0 text-v2-icon-icon-muted"
|
||||
/>
|
||||
<span class="min-w-0 truncate">{value()}</span>
|
||||
</div>
|
||||
</TooltipV2>
|
||||
)}
|
||||
</Show>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { For, Show, type ComponentProps, type JSX } from "solid-js"
|
|||
import { useLanguage } from "@/context/language"
|
||||
import { useServerSDK } from "@/context/server-sdk"
|
||||
import { useServerSync } from "@/context/server-sync"
|
||||
import { useSettingsDialog } from "@/components/settings-dialog"
|
||||
import { pathKey } from "@/utils/path-key"
|
||||
import { Worktree } from "@/utils/worktree"
|
||||
import { WorkspaceOperation } from "@/utils/workspace-operation"
|
||||
|
|
@ -35,6 +36,7 @@ export function SessionWorkspaceMenu(props: {
|
|||
const language = useLanguage()
|
||||
const serverSDK = useServerSDK()
|
||||
const serverSync = useServerSync()
|
||||
const openWorkspaces = useSettingsDialog("workspaces")
|
||||
const [store, setStore] = createStore({ selected: undefined as string | undefined })
|
||||
const operationPending = () => WorkspaceOperation.get(serverSDK().scope, props.sessionID)?.status === "pending"
|
||||
const blocked = () =>
|
||||
|
|
@ -126,28 +128,31 @@ export function SessionWorkspaceMenu(props: {
|
|||
<Icon name="workspace-new" />
|
||||
{language.t("workspace.new")}
|
||||
</MenuV2.Item>
|
||||
<Show when={workspaces().length > 0}>
|
||||
<MenuV2.Sub gutter={0} overlap overflowPadding={8}>
|
||||
<MenuV2.SubTrigger>
|
||||
<Icon name="workspace-isolated" />
|
||||
{language.t("session.new.workspace.existing").replace(/…$/, "")}
|
||||
</MenuV2.SubTrigger>
|
||||
<MenuV2.Portal>
|
||||
<MenuV2.SubContent class="w-[200px]">
|
||||
<For each={workspaces()}>
|
||||
{(workspace) => (
|
||||
<MenuV2.Item disabled={!!store.selected || blocked()} onSelect={() => void move(workspace)}>
|
||||
<Icon name="workspace-isolated" />
|
||||
<span class="min-w-0 flex-1 truncate">{getFilename(workspace)}</span>
|
||||
</MenuV2.Item>
|
||||
)}
|
||||
</For>
|
||||
</MenuV2.SubContent>
|
||||
</MenuV2.Portal>
|
||||
</MenuV2.Sub>
|
||||
</Show>
|
||||
</MenuV2.Group>
|
||||
<Show when={workspaces().length > 0}>
|
||||
<MenuV2.Separator class="h-[0.5px] bg-v2-border-border-base" />
|
||||
<MenuV2.Sub gutter={0} overlap overflowPadding={8}>
|
||||
<MenuV2.SubTrigger>
|
||||
<Icon name="workspace-isolated" />
|
||||
{language.t("session.new.workspace.existing").replace(/…$/, "")}
|
||||
</MenuV2.SubTrigger>
|
||||
<MenuV2.Portal>
|
||||
<MenuV2.SubContent class="w-[200px]">
|
||||
<For each={workspaces()}>
|
||||
{(workspace) => (
|
||||
<MenuV2.Item disabled={!!store.selected || blocked()} onSelect={() => void move(workspace)}>
|
||||
<Icon name="workspace-isolated" />
|
||||
<span class="min-w-0 flex-1 truncate">{getFilename(workspace)}</span>
|
||||
</MenuV2.Item>
|
||||
)}
|
||||
</For>
|
||||
</MenuV2.SubContent>
|
||||
</MenuV2.Portal>
|
||||
</MenuV2.Sub>
|
||||
</Show>
|
||||
<MenuV2.Separator class="h-[0.5px] bg-v2-border-border-base" />
|
||||
<MenuV2.Item onSelect={() => openWorkspaces()}>
|
||||
<span class="min-w-0 flex-1 truncate">{language.t("common.viewAll")}</span>
|
||||
</MenuV2.Item>
|
||||
</MenuV2.Content>
|
||||
</MenuV2.Portal>
|
||||
</MenuV2>
|
||||
|
|
|
|||
|
|
@ -784,8 +784,11 @@
|
|||
.settings-v2-workspaces-sessions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding-top: 4px;
|
||||
border: 0.5px solid var(--v2-border-border-base);
|
||||
border-radius: 4px;
|
||||
background-color: var(--v2-background-bg-base);
|
||||
overflow: hidden;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.settings-v2-workspaces-session {
|
||||
|
|
@ -794,26 +797,29 @@
|
|||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
overflow: hidden;
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 440;
|
||||
line-height: 16px;
|
||||
color: var(--v2-text-text-base);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.settings-v2-workspaces-session:not(:last-child) {
|
||||
border-bottom: 0.5px solid var(--v2-border-border-base);
|
||||
}
|
||||
|
||||
.settings-v2-workspaces-session > span:first-child {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.settings-v2-workspaces-session-active {
|
||||
.settings-v2-workspaces-session-time {
|
||||
flex-shrink: 0;
|
||||
color: var(--v2-text-text-muted);
|
||||
font-size: 11px;
|
||||
line-height: 14px;
|
||||
line-height: 1;
|
||||
color: var(--v2-text-text-muted);
|
||||
}
|
||||
|
||||
.settings-v2-workspaces-empty {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,10 @@ export const SettingsWorkspacesV2: Component<{ activeDirectory?: string }> = (pr
|
|||
if (!updated) return undefined
|
||||
return getRelativeTime(new Date(updated).toISOString(), language.t)
|
||||
}
|
||||
const sessionTime = (session: Session) => {
|
||||
if (!session.time.updated) return undefined
|
||||
return getRelativeTime(new Date(session.time.updated).toISOString(), language.t)
|
||||
}
|
||||
|
||||
const inspect = async (workspace: Workspace, context = captureDeleteContext()) => {
|
||||
const [status, sessions] = await Promise.all([
|
||||
|
|
@ -331,22 +335,29 @@ export const SettingsWorkspacesV2: Component<{ activeDirectory?: string }> = (pr
|
|||
</span>
|
||||
</TooltipV2>
|
||||
<Show when={lastActive(workspace)}>
|
||||
{(value) => <span class="settings-v2-workspaces-active">{value()}</span>}
|
||||
{(value) => (
|
||||
<TooltipV2
|
||||
value={language.t("settings.workspaces.lastActiveSession")}
|
||||
placement="top-end"
|
||||
>
|
||||
<span tabIndex={0} class="settings-v2-workspaces-active">
|
||||
{value()}
|
||||
</span>
|
||||
</TooltipV2>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
<span class="settings-v2-workspaces-meta">{sessionCount(workspace)}</span>
|
||||
<Show when={linked().length > 0}>
|
||||
<div class="settings-v2-workspaces-sessions">
|
||||
<For each={linked()}>
|
||||
{(session, index) => (
|
||||
<span class="settings-v2-workspaces-session">
|
||||
{(session) => (
|
||||
<div class="settings-v2-workspaces-session">
|
||||
<span>{session.title}</span>
|
||||
<Show when={index() === 0}>
|
||||
<span class="settings-v2-workspaces-session-active">
|
||||
{language.t("settings.workspaces.lastActiveSession")}
|
||||
</span>
|
||||
<Show when={sessionTime(session)}>
|
||||
{(time) => <span class="settings-v2-workspaces-session-time">{time()}</span>}
|
||||
</Show>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ function WorkspaceMoveAction(props: {
|
|||
classList={{
|
||||
"group/workspace-move relative shrink-0": true,
|
||||
"ml-auto h-5 w-[167px]": inline(),
|
||||
"-mt-2.5 h-[46px] w-full rounded-b-[6px] bg-v2-background-bg-layer-02 hover:bg-v2-background-bg-layer-03":
|
||||
"-mt-2.5 h-[46px] w-full rounded-b-[6px] bg-v2-background-bg-layer-02 hover:bg-v2-background-bg-layer-03 transition-colors":
|
||||
!inline(),
|
||||
invisible: props.dismissed,
|
||||
}}
|
||||
|
|
@ -286,10 +286,10 @@ function WorkspaceMoveAction(props: {
|
|||
class={
|
||||
inline()
|
||||
? "flex h-5 w-full items-center gap-1.5 rounded-[4px] pr-6 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-faint hover:bg-v2-overlay-simple-overlay-hover focus-visible:bg-v2-overlay-simple-overlay-hover focus-visible:outline-none data-[expanded]:bg-v2-overlay-simple-overlay-pressed"
|
||||
: "flex h-[46px] w-full items-center gap-1.5 rounded-b-[6px] px-3 pr-9 pt-[10px] text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-muted focus-visible:outline-none data-[expanded]:bg-v2-background-bg-layer-03"
|
||||
: "flex h-[46px] w-full items-center gap-2 rounded-b-[6px] px-3 pr-9 pt-2.5 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-muted focus-visible:outline-none"
|
||||
}
|
||||
>
|
||||
<IconV2 name={inline() ? "workspace-new" : "workspace"} class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<IconV2 name={inline() ? "workspace-new" : "workspace-new"} class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<span class="min-w-0 truncate">{language.t("workspace.move.title")}</span>
|
||||
</SessionWorkspaceMenu>
|
||||
<button
|
||||
|
|
@ -343,31 +343,21 @@ function SessionSummaryPanel(props: {
|
|||
src={getProjectAvatarSource(props.project.id, props.project.icon)}
|
||||
variant={getProjectAvatarVariant(props.project.icon?.color)}
|
||||
/>
|
||||
<span class="min-w-0 flex-1 truncate">{displayName(props.project)}</span>
|
||||
<span class="min-w-0 flex-1 truncate text-v2-text-text-muted">{displayName(props.project)}</span>
|
||||
</div>
|
||||
<Show
|
||||
when={props.local}
|
||||
fallback={
|
||||
<div class={row}>
|
||||
<IconV2 name="workspace-isolated" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<span class="min-w-0 flex-1 truncate">{location()}</span>
|
||||
</div>
|
||||
}
|
||||
<SessionWorkspaceMenu
|
||||
sessionID={props.sessionID}
|
||||
project={props.project}
|
||||
directory={props.directory}
|
||||
messageID={props.messageID}
|
||||
placement="left-start"
|
||||
gutter={-22}
|
||||
class={`${row} hover:bg-v2-overlay-simple-overlay-hover focus-visible:bg-v2-overlay-simple-overlay-hover focus-visible:outline-none data-[expanded]:bg-v2-overlay-simple-overlay-pressed`}
|
||||
>
|
||||
<SessionWorkspaceMenu
|
||||
sessionID={props.sessionID}
|
||||
project={props.project}
|
||||
directory={props.directory}
|
||||
messageID={props.messageID}
|
||||
placement="left-start"
|
||||
gutter={-22}
|
||||
class={`${row} hover:bg-v2-overlay-simple-overlay-hover focus-visible:bg-v2-overlay-simple-overlay-hover focus-visible:outline-none data-[expanded]:bg-v2-overlay-simple-overlay-pressed`}
|
||||
>
|
||||
<IconV2 name="monitor" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<span class="min-w-0 flex-1 truncate text-left">{location()}</span>
|
||||
<IconV2 name="chevron-down" size="small" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
</SessionWorkspaceMenu>
|
||||
</Show>
|
||||
<IconV2 name={props.local ? "monitor" : "workspace-isolated"} class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<span class="min-w-0 flex-1 truncate text-left">{location()}</span>
|
||||
<IconV2 name="chevron-down" size="small" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
</SessionWorkspaceMenu>
|
||||
<div class={row}>
|
||||
<IconV2 name="branch" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<Show
|
||||
|
|
@ -1453,27 +1443,33 @@ export function MessageTimeline(props: {
|
|||
return (
|
||||
<TimelineRowFrame row={workspaceRow}>
|
||||
<div class={`w-full ${turnPadding()}`} aria-live="polite">
|
||||
<div class="flex h-11 w-full items-center gap-2 text-[13px] font-[440] leading-5 tracking-[-0.04px]">
|
||||
<span class="h-px min-w-0 flex-1 bg-v2-border-border-muted" />
|
||||
<Show when={!pending()} fallback={<TextShimmer text={status()} />}>
|
||||
<span
|
||||
<div class="flex h-7 items-center py-1 text-[13px] font-[440] leading-none tracking-[-0.04px]">
|
||||
<Show
|
||||
when={!pending()}
|
||||
fallback={
|
||||
<div class="flex items-center gap-1.5">
|
||||
<TextShimmer text={status()} />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
classList={{
|
||||
"flex min-w-0 items-center gap-1.5": true,
|
||||
"flex items-center gap-1.5": true,
|
||||
"text-v2-state-fg-danger": operation().status === "failed",
|
||||
}}
|
||||
>
|
||||
<Show when={operation().status !== "failed"}>
|
||||
<IconV2 name="workspace-isolated" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
</Show>
|
||||
<Show when={directory()}>
|
||||
<span class="max-w-[240px] truncate text-v2-text-text-base">{directory()}</span>
|
||||
</Show>
|
||||
<span class={operation().status === "failed" ? "" : "text-v2-text-text-faint lowercase"}>
|
||||
<span class={operation().status === "failed" ? "" : "text-v2-text-text-base"}>
|
||||
{status()}
|
||||
</span>
|
||||
</span>
|
||||
<Show when={operation().status !== "failed"}>
|
||||
<span class="text-[11px] font-[530] italic text-v2-text-text-muted">·</span>
|
||||
<IconV2 name="workspace-isolated" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<Show when={directory()}>
|
||||
<span class="max-w-[240px] truncate text-v2-text-text-base">{directory()}</span>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
<span class="h-px min-w-0 flex-1 bg-v2-border-border-muted" />
|
||||
</div>
|
||||
</div>
|
||||
</TimelineRowFrame>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ const icons = {
|
|||
viewBox: "0 0 16 16",
|
||||
body: `<path d="M5.118 5.686V10.314M5.118 5.686C5.97 5.686 6.661 4.995 6.661 4.143C6.661 3.291 5.97 2.6 5.118 2.6C4.266 2.6 3.575 3.291 3.575 4.143C3.575 4.995 4.266 5.686 5.118 5.686ZM5.118 10.314C4.266 10.314 3.575 11.005 3.575 11.857C3.575 12.709 4.266 13.4 5.118 13.4C5.97 13.4 6.661 12.709 6.661 11.857M5.118 10.314C5.97 10.314 6.661 11.005 6.661 11.857M10.882 5.686C11.734 5.686 12.425 4.995 12.425 4.143C12.425 3.291 11.734 2.6 10.882 2.6C10.03 2.6 9.339 3.291 9.339 4.143C9.339 4.995 10.03 5.686 10.882 5.686ZM10.882 5.686V9.457C10.882 10.783 9.807 11.857 8.482 11.857H6.661" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>`,
|
||||
},
|
||||
"branch-out": {
|
||||
viewBox: "0 0 16 16",
|
||||
body: `<path d="M10.4225 3.35355L12.9024 5.83344L10.4225 8.31333" stroke="currentColor"/><path d="M1 12.2852H4.23042C4.89912 12.2852 5.52359 11.951 5.89452 11.3946L9.00783 6.72462C8.37877 6.16823 10.0032 5.83402 10.6719 5.83402H12.9024" stroke="currentColor"/><path d="M8.5 12.2852H14" stroke="currentColor" stroke-linejoin="round"/>`,
|
||||
},
|
||||
"grid-plus": {
|
||||
viewBox: "0 0 16 16",
|
||||
body: `<path d="M13.9948 11.668H9.32812M11.6641 9.33203V13.9987M6.66667 9.33203V13.9987H2V9.33203H6.66667ZM6.66667 2V6.66667H2V2H6.66667ZM13.9948 2V6.66667H9.32812V2H13.9948Z" stroke="currentColor" stroke-miterlimit="10" stroke-linecap="square"/>`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue