| author | |
| committer | |
| log | 4c1d99d7f3e722c5e88c0dda6a96f9de8f296115 |
| tree | b3447135d4336ca1e56d4bc6b516db75f3cdce71 |
| parent | 4cb676cc1612e6220246cd5f8abdd2bc284e1a97 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>3 files changed, 62 insertions(+), 6 deletions(-)
apps/web/src/components/GitActionsControl.tsx+6-6| ... | @@ -51,6 +51,7 @@ import { | ... | @@ -51,6 +51,7 @@ import { |
| 51 | resolveThreadBranchUpdate, | 51 | resolveThreadBranchUpdate, |
| 52 | } from "./GitActionsControl.logic"; | 52 | } from "./GitActionsControl.logic"; |
| 53 | import { AnimatedHeight } from "./AnimatedHeight"; | 53 | import { AnimatedHeight } from "./AnimatedHeight"; |
| 54 | import { StartTruncatedPath } from "./StartTruncatedPath"; | ||
| 54 | import { Button } from "~/components/ui/button"; | 55 | import { Button } from "~/components/ui/button"; |
| 55 | import { Checkbox } from "~/components/ui/checkbox"; | 56 | import { Checkbox } from "~/components/ui/checkbox"; |
| 56 | import { | 57 | import { |
| ... | @@ -1923,14 +1924,13 @@ export default function GitActionsControl({ | ... | @@ -1923,14 +1924,13 @@ export default function GitActionsControl({ |
| 1923 | )} | 1924 | )} |
| 1924 | <button | 1925 | <button |
| 1925 | type="button" | 1926 | type="button" |
| 1926 | className="flex flex-1 items-center justify-between gap-3 text-left truncate" | 1927 | className="flex min-w-0 flex-1 items-center justify-between gap-3 text-left" |
| 1927 | onClick={() => openChangedFileInEditor(file.path)} | 1928 | onClick={() => openChangedFileInEditor(file.path)} |
| 1928 | > | 1929 | > |
| 1929 | <span | 1930 | <StartTruncatedPath |
| 1930 | className={`truncate${isExcluded ? " text-muted-foreground" : ""}`} | 1931 | path={file.path} |
| 1931 | > | 1932 | className={`flex-1${isExcluded ? " text-muted-foreground" : ""}`} |
| 1932 | {file.path} | 1933 | /> |
| 1933 | </span> | ||
| 1934 | <span className="shrink-0"> | 1934 | <span className="shrink-0"> |
| 1935 | {isExcluded ? ( | 1935 | {isExcluded ? ( |
| 1936 | <span className="text-muted-foreground">Excluded</span> | 1936 | <span className="text-muted-foreground">Excluded</span> |
apps/web/src/components/StartTruncatedPath.test.tsx created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | import { renderToStaticMarkup } from "react-dom/server"; | ||
| 2 | import { describe, expect, it } from "vite-plus/test"; | ||
| 3 | |||
| 4 | import { StartTruncatedPath } from "./StartTruncatedPath"; | ||
| 5 | |||
| 6 | describe("StartTruncatedPath", () => { | ||
| 7 | it("keeps the filename at the visible end by truncating from the start", () => { | ||
| 8 | const path = "apps/desktop/src/components/very/long/CommitDialog.tsx"; | ||
| 9 | |||
| 10 | const markup = renderToStaticMarkup(<StartTruncatedPath path={path} />); | ||
| 11 | |||
| 12 | expect(markup).toContain('dir="rtl"'); | ||
| 13 | expect(markup).toMatch( | ||
| 14 | /<bdi[^>]*>apps\/desktop\/src\/components\/very\/long\/CommitDialog\.tsx<\/bdi>/, | ||
| 15 | ); | ||
| 16 | expect(markup).toContain("overflow-hidden"); | ||
| 17 | expect(markup).toContain("text-ellipsis"); | ||
| 18 | expect(markup).toContain("whitespace-nowrap"); | ||
| 19 | expect(markup).toContain("min-w-0"); | ||
| 20 | }); | ||
| 21 | |||
| 22 | it("shows the full path in a tooltip", () => { | ||
| 23 | const path = "apps/desktop/src/components/very/long/CommitDialog.tsx"; | ||
| 24 | |||
| 25 | const markup = renderToStaticMarkup(<StartTruncatedPath path={path} />); | ||
| 26 | |||
| 27 | expect(markup).toContain('data-slot="tooltip-trigger"'); | ||
| 28 | expect(markup).toContain("data-base-ui-tooltip-trigger"); | ||
| 29 | expect(markup).toContain(path); | ||
| 30 | }); | ||
| 31 | }); | ||
apps/web/src/components/StartTruncatedPath.tsx created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip"; | ||
| 2 | import { cn } from "~/lib/utils"; | ||
| 3 | |||
| 4 | export function StartTruncatedPath({ path, className }: { path: string; className?: string }) { | ||
| 5 | return ( | ||
| 6 | <Tooltip> | ||
| 7 | <TooltipTrigger | ||
| 8 | render={ | ||
| 9 | <span | ||
| 10 | className={cn( | ||
| 11 | "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap text-left", | ||
| 12 | className, | ||
| 13 | )} | ||
| 14 | dir="rtl" | ||
| 15 | /> | ||
| 16 | } | ||
| 17 | > | ||
| 18 | <bdi>{path}</bdi> | ||
| 19 | </TooltipTrigger> | ||
| 20 | <TooltipPopup side="top" className="max-w-sm break-all font-mono"> | ||
| 21 | {path} | ||
| 22 | </TooltipPopup> | ||
| 23 | </Tooltip> | ||
| 24 | ); | ||
| 25 | } | ||