Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,25 @@ import {
import { HiMiniXMark } from "react-icons/hi2";
import type { DiffStats } from "renderer/hooks/host-service/useDiffStats";
import { HotkeyLabel } from "renderer/hotkeys";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { RenameInput } from "renderer/screens/main/components/WorkspaceSidebar/RenameInput";
import type { DashboardSidebarWorkspace } from "../../../../types";
import type {
DashboardSidebarWorkspace,
DashboardSidebarWorkspacePullRequest,
} from "../../../../types";
import { getCreationStatusText } from "../../utils/getCreationStatusText";
import { DashboardSidebarWorkspaceDiffStats } from "../DashboardSidebarWorkspaceDiffStats";
import { DashboardSidebarWorkspaceIcon } from "../DashboardSidebarWorkspaceIcon";
import { DashboardSidebarWorkspaceStatusBadge } from "../DashboardSidebarWorkspaceStatusBadge";

const PR_STATE_LABEL: Record<
DashboardSidebarWorkspacePullRequest["state"],
string
> = {
open: "Open",
merged: "Merged",
closed: "Closed",
draft: "Draft",
};

interface DashboardSidebarExpandedWorkspaceRowProps
extends ComponentPropsWithoutRef<"div"> {
Expand Down Expand Up @@ -67,6 +80,7 @@ export const DashboardSidebarExpandedWorkspaceRow = forwardRef<
} = workspace;
const showsStandaloneActiveStripe = accentColor == null;
const localRef = useRef<HTMLDivElement>(null);
const openUrl = electronTrpc.external.openUrl.useMutation();

useEffect(() => {
if (isActive) {
Expand Down Expand Up @@ -120,36 +134,77 @@ export const DashboardSidebarExpandedWorkspaceRow = forwardRef<

<Tooltip delayDuration={500}>
<TooltipTrigger asChild>
<div className="relative mr-2.5 flex size-5 shrink-0 items-center justify-center">
<DashboardSidebarWorkspaceIcon
hostType={hostType}
hostIsOnline={hostIsOnline}
isActive={isActive}
variant="expanded"
workspaceStatus={null}
creationStatus={creationStatus}
/>
</div>
{pullRequest ? (
<button
type="button"
onClick={(event) => {
event.stopPropagation();
openUrl.mutate(pullRequest.url);
}}
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.stopPropagation();
}
}}
aria-label={`Open pull request #${pullRequest.number}`}
className="relative mr-2.5 flex size-5 shrink-0 cursor-pointer items-center justify-center rounded hover:bg-foreground/10"
>
<DashboardSidebarWorkspaceIcon
hostType={hostType}
hostIsOnline={hostIsOnline}
isActive={isActive}
variant="expanded"
workspaceStatus={null}
creationStatus={creationStatus}
pullRequestState={pullRequest.state}
/>
</button>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
) : (
<div className="relative mr-2.5 flex size-5 shrink-0 items-center justify-center">
<DashboardSidebarWorkspaceIcon
hostType={hostType}
hostIsOnline={hostIsOnline}
isActive={isActive}
variant="expanded"
workspaceStatus={null}
creationStatus={creationStatus}
pullRequestState={null}
/>
</div>
)}
</TooltipTrigger>
<TooltipContent side="right" sideOffset={8}>
<p className="text-xs font-medium">
{hostType === "local-device"
? "Local workspace"
: hostType === "remote-device"
? hostIsOnline === false
? "Remote workspace — device offline"
: "Remote workspace"
: "Cloud workspace"}
</p>
<p className="text-xs text-muted-foreground">
{hostType === "local-device"
? "Running on this device"
: hostType === "remote-device"
? hostIsOnline === false
? "The associated device isn't reachable right now"
: "Running on a paired device"
: "Hosted in the cloud"}
</p>
{pullRequest ? (
<>
<p className="text-xs font-medium">
PR #{pullRequest.number} — {PR_STATE_LABEL[pullRequest.state]}
</p>
<p className="text-xs text-muted-foreground">
Click to open on GitHub
</p>
</>
) : (
<>
<p className="text-xs font-medium">
{hostType === "local-device"
? "Local workspace"
: hostType === "remote-device"
? hostIsOnline === false
? "Remote workspace — device offline"
: "Remote workspace"
: "Cloud workspace"}
</p>
<p className="text-xs text-muted-foreground">
{hostType === "local-device"
? "Running on this device"
: hostType === "remote-device"
? hostIsOnline === false
? "The associated device isn't reachable right now"
: "Running on a paired device"
: "Hosted in the cloud"}
</p>
</>
)}
</TooltipContent>
</Tooltip>

Expand Down Expand Up @@ -233,15 +288,6 @@ export const DashboardSidebarExpandedWorkspaceRow = forwardRef<
<span className="col-start-1 row-start-2 truncate font-mono text-[11px] leading-tight text-muted-foreground/60">
{branch}
</span>

{pullRequest && (
<DashboardSidebarWorkspaceStatusBadge
state={pullRequest.state}
prNumber={pullRequest.number}
prUrl={pullRequest.url}
className="col-start-2 row-start-2 justify-self-end"
/>
)}
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { cn } from "@superset/ui/utils";

interface DashboardSidebarWorkspaceDiffStatsProps {
additions: number;
deletions: number;
Expand All @@ -12,15 +10,18 @@ export function DashboardSidebarWorkspaceDiffStats({
isActive,
}: DashboardSidebarWorkspaceDiffStatsProps) {
return (
<div
className={cn(
"flex h-5 w-fit shrink-0 items-center justify-self-end rounded px-1.5 text-[10px] font-mono tabular-nums transition-[opacity,visibility] group-hover:opacity-0 group-hover:invisible",
isActive ? "bg-foreground/10" : "bg-muted/50",
)}
>
<div className="flex h-5 w-fit shrink-0 items-center justify-self-end text-[10px] font-mono tabular-nums transition-[opacity,visibility] group-hover:opacity-0 group-hover:invisible">
<div className="flex items-center gap-1.5 leading-none">
<span className="text-emerald-500/90">+{additions}</span>
<span className="text-red-400/90">−{deletions}</span>
<span
className={isActive ? "text-emerald-500/90" : "text-muted-foreground"}
>
+{additions}
</span>
<span
className={isActive ? "text-red-400/90" : "text-muted-foreground"}
>
−{deletions}
</span>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { cn } from "@superset/ui/utils";
import { HiExclamationTriangle } from "react-icons/hi2";
import { LuCloud, LuCloudOff } from "react-icons/lu";
import {
LuCloud,
LuCloudOff,
LuGitMerge,
LuGitPullRequest,
LuGitPullRequestClosed,
LuGitPullRequestDraft,
} from "react-icons/lu";
import { AsciiSpinner } from "renderer/screens/main/components/AsciiSpinner";
import { StatusIndicator } from "renderer/screens/main/components/StatusIndicator";
import type { ActivePaneStatus } from "shared/tabs-types";
import type { DashboardSidebarWorkspaceHostType } from "../../../../types";
import type {
DashboardSidebarWorkspaceHostType,
DashboardSidebarWorkspacePullRequest,
} from "../../../../types";

interface DashboardSidebarWorkspaceIconProps {
hostType: DashboardSidebarWorkspaceHostType;
Expand All @@ -13,27 +23,53 @@ interface DashboardSidebarWorkspaceIconProps {
variant: "collapsed" | "expanded";
workspaceStatus?: ActivePaneStatus | null;
creationStatus?: "preparing" | "generating-branch" | "creating" | "failed";
pullRequestState?: DashboardSidebarWorkspacePullRequest["state"] | null;
}

const OVERLAY_POSITION = {
collapsed: "top-1 right-1",
expanded: "-top-0.5 -right-0.5",
} as const;

const PR_ICON_BY_STATE = {
open: LuGitPullRequest,
merged: LuGitMerge,
closed: LuGitPullRequestClosed,
draft: LuGitPullRequestDraft,
} as const;

const PR_COLOR_BY_STATE = {
open: "text-emerald-500",
merged: "text-purple-500",
closed: "text-destructive",
draft: "text-muted-foreground",
} as const;

export function DashboardSidebarWorkspaceIcon({
hostType,
hostIsOnline,
isActive,
variant,
workspaceStatus = null,
creationStatus,
pullRequestState = null,
}: DashboardSidebarWorkspaceIconProps) {
const overlayPosition = OVERLAY_POSITION[variant];
const iconColor = isActive ? "text-foreground" : "text-muted-foreground";
const isRemoteDeviceOffline =
hostType === "remote-device" && hostIsOnline === false;

const renderHostIcon = () => {
const renderPrimaryIcon = () => {
if (pullRequestState) {
const PrIcon = PR_ICON_BY_STATE[pullRequestState];
return (
<PrIcon
className={cn("size-3.5", PR_COLOR_BY_STATE[pullRequestState])}
strokeWidth={1.75}
/>
);
}

if (hostType === "local-device") {
return (
<span
Expand Down Expand Up @@ -69,7 +105,7 @@ export function DashboardSidebarWorkspaceIcon({
) : creationStatus || workspaceStatus === "working" ? (
<AsciiSpinner className="text-base" />
) : (
renderHostIcon()
renderPrimaryIcon()
)}
{workspaceStatus && workspaceStatus !== "working" && (
<span className={cn("absolute", overlayPosition)}>
Expand Down
Loading