Simplify sidebar workspace status indicator

Hide the kind icon entirely when a workspace is idle, and give the
attention state a standalone dot instead of overlaying it on the icon.
Restructure the row into an icon column plus a content column so the
subtitle and PR badge align under the title without hardcoded indents.
This commit is contained in:
Mohamed Boudra
2026-06-18 12:56:18 +07:00
parent 4e899c644a
commit 3163c7d09b

View File

@@ -124,35 +124,39 @@ export const SidebarWorkspaceRowContent = memo(function SidebarWorkspaceRowConte
return (
<View style={styles.workspaceRowContent}>
<View style={styles.workspaceRowMain}>
<View style={styles.workspaceRowLeft}>
<WorkspaceStatusIndicator
bucket={workspace.statusBucket}
workspaceKind={workspace.workspaceKind}
loading={isLoading}
/>
<Text style={workspaceBranchTextStyle} numberOfLines={1}>
{workspace.name}
</Text>
{scriptIconKind ? <WorkspaceScriptIcon kind={scriptIconKind} /> : null}
<WorkspaceStatusIndicator
bucket={workspace.statusBucket}
workspaceKind={workspace.workspaceKind}
loading={isLoading}
/>
<View style={styles.workspaceContentColumn}>
<View style={styles.workspaceTitleRow}>
<View style={styles.workspaceTitleLeft}>
<Text style={workspaceBranchTextStyle} numberOfLines={1}>
{workspace.name}
</Text>
{scriptIconKind ? <WorkspaceScriptIcon kind={scriptIconKind} /> : null}
</View>
<View style={styles.workspaceRowRight}>{children}</View>
</View>
{subtitle ? (
<Text style={styles.workspaceSubtitle} numberOfLines={1}>
{subtitle}
</Text>
) : null}
{workspace.prHint ? (
<View style={styles.workspacePrBadgeRow}>
<PrBadge hint={workspace.prHint} />
<ChecksBadge checks={workspace.prHint.checks} />
</View>
) : null}
</View>
<View style={styles.workspaceRowRight}>{children}</View>
</View>
{showShortcutBadge && shortcutNumber !== null ? (
<View style={styles.shortcutBadgeOverlay} pointerEvents="none">
<SidebarWorkspaceShortcutBadge number={shortcutNumber} />
</View>
) : null}
{subtitle ? (
<Text style={styles.workspaceSubtitle} numberOfLines={1}>
{subtitle}
</Text>
) : null}
{workspace.prHint ? (
<View style={styles.workspacePrBadgeRow}>
<PrBadge hint={workspace.prHint} />
<ChecksBadge checks={workspace.prHint.checks} />
</View>
) : null}
</View>
);
});
@@ -208,6 +212,16 @@ function WorkspaceStatusIndicator({
);
}
if (bucket === "attention") {
return (
<View style={styles.workspaceStatusDot} testID="workspace-status-indicator-attention">
<View style={styles.standaloneStatusDot} />
</View>
);
}
if (bucket === "done") return null;
let KindIcon: typeof ThemedMonitor;
if (workspaceKind === "local_checkout") KindIcon = ThemedMonitor;
else if (workspaceKind === "worktree") KindIcon = ThemedFolderGit2;
@@ -461,11 +475,20 @@ const styles = StyleSheet.create((theme) => ({
workspaceRowMain: {
flexDirection: "row",
alignItems: "flex-start",
justifyContent: "space-between",
gap: theme.spacing[2],
width: "100%",
},
workspaceRowLeft: {
workspaceContentColumn: {
flex: 1,
minWidth: 0,
},
workspaceTitleRow: {
flexDirection: "row",
alignItems: "flex-start",
justifyContent: "space-between",
gap: theme.spacing[2],
},
workspaceTitleLeft: {
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[2],
@@ -492,6 +515,12 @@ const styles = StyleSheet.create((theme) => ({
borderRadius: theme.borderRadius.full,
borderWidth: 1,
},
standaloneStatusDot: {
width: 8,
height: 8,
borderRadius: theme.borderRadius.full,
backgroundColor: theme.colors.palette.green[500],
},
workspaceBranchText: {
color: theme.colors.foreground,
fontSize: theme.fontSize.sm,
@@ -522,14 +551,12 @@ const styles = StyleSheet.create((theme) => ({
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.xs,
lineHeight: 14,
marginLeft: WORKSPACE_STATUS_DOT_WIDTH + theme.spacing[2],
},
workspacePrBadgeRow: {
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[2],
marginTop: theme.spacing[1],
paddingLeft: WORKSPACE_STATUS_DOT_WIDTH + theme.spacing[2],
},
statusDotNeedsInput: {
backgroundColor: theme.colors.palette.amber[500],