From 1547a6d525e57278f2da1a1d6b9326428bab996f Mon Sep 17 00:00:00 2001 From: Dinesh Pandiyan Date: Sat, 10 Oct 2026 23:25:58 +1100 Subject: [PATCH] Show file change types inline in summary --- DESIGN.md | 3 + apps/web/src/ReviewTools.tsx | 62 ++++++++++++++++++- apps/web/src/review.css | 2 +- apps/web/src/style.css | 41 ++++++++++++ apps/web/test/browser/app.spec.ts | 36 +++++++++++ ...l-zSUgWMpk.js => angular-html-CXf32AcN.js} | 2 +- ...-ts-svdTVWoR.js => angular-ts-DJW2Kg-P.js} | 2 +- .../{apl-BoUWP9tl.js => apl-q_-s_TGZ.js} | 2 +- .../{astro-DQRzsDmW.js => astro-CJVz5Clq.js} | 2 +- .../{blade-BTXKADPL.js => blade-CaTnJ6RM.js} | 2 +- .../assets/{c-BCPnEPW2.js => c-DDSp95RX.js} | 2 +- ...{chapel-Bgp4o5F6.js => chapel-DqspHXl0.js} | 2 +- .../{cobol-CsRAtnBM.js => cobol-BD3gonAE.js} | 2 +- ...{coffee-ESLpn3Ng.js => coffee-B_MpiBwF.js} | 2 +- .../{cpp-CxzGJkpn.js => cpp-V7GFWQ0y.js} | 2 +- ...rystal-CjeBo4Rn.js => crystal-e9cEPtzg.js} | 2 +- .../{css-CwFTKazM.js => css-_2rI0llv.js} | 2 +- .../{edge-CH77v7Rh.js => edge-oJXrbNM4.js} | 2 +- ...{elixir-DaeOXO6I.js => elixir-en9Qg_SQ.js} | 2 +- .../{elm-DrWZzBLE.js => elm-5XczTgvK.js} | 2 +- .../{erb-DVX3oVeX.js => erb-DdMuMRzQ.js} | 2 +- ...ase-Bl_WgM9-.js => git-rebase-DqSa-smA.js} | 2 +- ...-js-BjpdQiOz.js => glimmer-js-C2SDWq2D.js} | 2 +- ...-ts-CiEW6dQV.js => glimmer-ts-mxnvfyph.js} | 2 +- .../{glsl-EigoVbzb.js => glsl-DnmYg1bZ.js} | 2 +- ...raphql-DFmvbzSQ.js => graphql-B0Eq4aiT.js} | 2 +- .../{hack-BHL-Lnyd.js => hack-Hpccj27m.js} | 2 +- .../{haml-D1Ha8m_O.js => haml-bkaebTrI.js} | 2 +- ...ars-BwsEH0z0.js => handlebars-Cp_RZvXv.js} | 2 +- .../{html-gNH17JjG.js => html-DZv9I9Nb.js} | 2 +- ...5QuIZJD.js => html-derivative-C4x9DB2m.js} | 2 +- .../{http-D2W05MP3.js => http-_Cyqgmc4.js} | 2 +- .../{hurl-DHkypP4c.js => hurl-CDx9EySR.js} | 2 +- ...{index-DOSf590M.css => index-BjYgOSV3.css} | 2 +- .../{index-DPa5LVln.js => index-qOEe3EB3.js} | 18 +++--- .../{java-BUWdBgj9.js => java-lPyWLB2l.js} | 2 +- ...ipt-DhmqKr97.js => javascript-CqSN-VcJ.js} | 2 +- .../{jinja-DH3Gs40R.js => jinja-DVHpI3Ji.js} | 2 +- .../{jison-BNsSg4a3.js => jison-JjSvqOOl.js} | 2 +- .../{json-MZX8yIm7.js => json-CWkLxD_y.js} | 2 +- .../{jsx-WN-a52A1.js => jsx-DBHRmZyL.js} | 2 +- .../{julia-BLK-ZwfB.js => julia-DWFTltGQ.js} | 2 +- .../{just-BvJ0CBgj.js => just-Bmhoe9gt.js} | 2 +- .../{latex-CNJ-q3i3.js => latex-Bcxee-PR.js} | 2 +- ...{liquid-CZKI6pLp.js => liquid-BeP_3myT.js} | 2 +- .../{lua-DJl7ho0D.js => lua-CSRt83hE.js} | 2 +- .../{marko-DxLYQZnE.js => marko-BU7uox9g.js} | 2 +- .../{mdc-n-CQKnQx.js => mdc-D_tH3DHW.js} | 2 +- .../{nginx-CION907h.js => nginx-CE8daTSk.js} | 2 +- .../{nim-Dzpio92F.js => nim-C90aJxat.js} | 2 +- .../{org-BvC1nNcX.js => org-BWWOHulA.js} | 2 +- .../{perl-FWmJiLAv.js => perl-DzXlbSFI.js} | 2 +- .../{php-Cs9OQtG7.js => php-B2g8KKRt.js} | 2 +- .../{pug-LuggxQtI.js => pug-BiwjVDkK.js} | 2 +- .../{qml-cR0dLM4Z.js => qml-DPu7AuZ_.js} | 2 +- .../assets/{r-D5GoUSdE.js => r-CaZx80xz.js} | 2 +- .../{razor-CR0Ji7pe.js => razor-BgTeCNoL.js} | 2 +- ...{regexp-C6xScJlk.js => regexp-CkmzLcBD.js} | 2 +- .../{rst-CF6V6ePx.js => rst-BetBoc7w.js} | 2 +- .../{ruby-R3F_6Mdo.js => ruby-iZlDYJk9.js} | 2 +- .../{sas-zH5LzPCf.js => sas-Bw60vxj-.js} | 2 +- .../{scss-ZEAZglbY.js => scss-f6sjw7k_.js} | 2 +- ...pt-B8ftsUqb.js => shellscript-BL3fFvD_.js} | 2 +- ...n-P069U12g.js => shellsession-CC2I9JKe.js} | 2 +- .../{soy-CKoWzens.js => soy-DKAl9I0F.js} | 2 +- .../{sql-QEMNPZ4T.js => sql-IaP04OFe.js} | 2 +- .../{stata-BiTjf37T.js => stata-Dv_6cn9o.js} | 2 +- ...alql-Wm_CIXs5.js => surrealql-DmbcuQy8.js} | 2 +- ...{svelte-0pmI4uLE.js => svelte-uMxbmgXS.js} | 2 +- .../{templ--PeeJH2H.js => templ-B78ksfer.js} | 2 +- .../{tex-DaemZuNL.js => tex-CaGRzAG_.js} | 2 +- ...s-tags-BQ15nl3d.js => ts-tags-CNYG2Eot.js} | 2 +- .../{tsx-D7VJyEh5.js => tsx-C-FjrBVW.js} | 2 +- .../{twig-CL7zAR6w.js => twig-8BdDMjEc.js} | 2 +- ...ipt-B0CFpljX.js => typescript-CRJ68kce.js} | 2 +- .../{typst-BREik9O1.js => typst-B0KuliC2.js} | 2 +- .../{vue-CGCjzvrH.js => vue-BwtkPb4P.js} | 2 +- ...-html-Bx0Y_gr3.js => vue-html-DuI7L0W7.js} | 2 +- ...-vine-7Ywe39of.js => vue-vine-Du2VWbMb.js} | 2 +- .../{xml-KmXNDLBK.js => xml-DDJpq1Oa.js} | 2 +- .../{xsl-HCdC-ABc.js => xsl-Bop51BZ5.js} | 2 +- .../{yaml-BIsyNzg5.js => yaml-CnVvXmYQ.js} | 2 +- internal/webui/dist/index.html | 4 +- 83 files changed, 227 insertions(+), 91 deletions(-) rename internal/webui/dist/assets/{angular-html-zSUgWMpk.js => angular-html-CXf32AcN.js} (99%) rename internal/webui/dist/assets/{angular-ts-svdTVWoR.js => angular-ts-DJW2Kg-P.js} (99%) rename internal/webui/dist/assets/{apl-BoUWP9tl.js => apl-q_-s_TGZ.js} (99%) rename internal/webui/dist/assets/{astro-DQRzsDmW.js => astro-CJVz5Clq.js} (98%) rename internal/webui/dist/assets/{blade-BTXKADPL.js => blade-CaTnJ6RM.js} (99%) rename internal/webui/dist/assets/{c-BCPnEPW2.js => c-DDSp95RX.js} (99%) rename internal/webui/dist/assets/{chapel-Bgp4o5F6.js => chapel-DqspHXl0.js} (99%) rename internal/webui/dist/assets/{cobol-CsRAtnBM.js => cobol-BD3gonAE.js} (99%) rename internal/webui/dist/assets/{coffee-ESLpn3Ng.js => coffee-B_MpiBwF.js} (99%) rename internal/webui/dist/assets/{cpp-CxzGJkpn.js => cpp-V7GFWQ0y.js} (99%) rename internal/webui/dist/assets/{crystal-CjeBo4Rn.js => crystal-e9cEPtzg.js} (99%) rename internal/webui/dist/assets/{css-CwFTKazM.js => css-_2rI0llv.js} (99%) rename internal/webui/dist/assets/{edge-CH77v7Rh.js => edge-oJXrbNM4.js} (94%) rename internal/webui/dist/assets/{elixir-DaeOXO6I.js => elixir-en9Qg_SQ.js} (99%) rename internal/webui/dist/assets/{elm-DrWZzBLE.js => elm-5XczTgvK.js} (99%) rename internal/webui/dist/assets/{erb-DVX3oVeX.js => erb-DdMuMRzQ.js} (94%) rename internal/webui/dist/assets/{git-rebase-Bl_WgM9-.js => git-rebase-DqSa-smA.js} (93%) rename internal/webui/dist/assets/{glimmer-js-BjpdQiOz.js => glimmer-js-C2SDWq2D.js} (99%) rename internal/webui/dist/assets/{glimmer-ts-CiEW6dQV.js => glimmer-ts-mxnvfyph.js} (99%) rename internal/webui/dist/assets/{glsl-EigoVbzb.js => glsl-DnmYg1bZ.js} (96%) rename internal/webui/dist/assets/{graphql-DFmvbzSQ.js => graphql-B0Eq4aiT.js} (98%) rename internal/webui/dist/assets/{hack-BHL-Lnyd.js => hack-Hpccj27m.js} (99%) rename internal/webui/dist/assets/{haml-D1Ha8m_O.js => haml-bkaebTrI.js} (98%) rename internal/webui/dist/assets/{handlebars-BwsEH0z0.js => handlebars-Cp_RZvXv.js} (98%) rename internal/webui/dist/assets/{html-gNH17JjG.js => html-DZv9I9Nb.js} (99%) rename internal/webui/dist/assets/{html-derivative-B5QuIZJD.js => html-derivative-C4x9DB2m.js} (92%) rename internal/webui/dist/assets/{http-D2W05MP3.js => http-_Cyqgmc4.js} (95%) rename internal/webui/dist/assets/{hurl-DHkypP4c.js => hurl-CDx9EySR.js} (96%) rename internal/webui/dist/assets/{index-DOSf590M.css => index-BjYgOSV3.css} (59%) rename internal/webui/dist/assets/{index-DPa5LVln.js => index-qOEe3EB3.js} (84%) rename internal/webui/dist/assets/{java-BUWdBgj9.js => java-lPyWLB2l.js} (99%) rename internal/webui/dist/assets/{javascript-DhmqKr97.js => javascript-CqSN-VcJ.js} (99%) rename internal/webui/dist/assets/{jinja-DH3Gs40R.js => jinja-DVHpI3Ji.js} (98%) rename internal/webui/dist/assets/{jison-BNsSg4a3.js => jison-JjSvqOOl.js} (99%) rename internal/webui/dist/assets/{json-MZX8yIm7.js => json-CWkLxD_y.js} (97%) rename internal/webui/dist/assets/{jsx-WN-a52A1.js => jsx-DBHRmZyL.js} (99%) rename internal/webui/dist/assets/{julia-BLK-ZwfB.js => julia-DWFTltGQ.js} (99%) rename internal/webui/dist/assets/{just-BvJ0CBgj.js => just-Bmhoe9gt.js} (97%) rename internal/webui/dist/assets/{latex-CNJ-q3i3.js => latex-Bcxee-PR.js} (99%) rename internal/webui/dist/assets/{liquid-CZKI6pLp.js => liquid-BeP_3myT.js} (98%) rename internal/webui/dist/assets/{lua-DJl7ho0D.js => lua-CSRt83hE.js} (99%) rename internal/webui/dist/assets/{marko-DxLYQZnE.js => marko-BU7uox9g.js} (99%) rename internal/webui/dist/assets/{mdc-n-CQKnQx.js => mdc-D_tH3DHW.js} (99%) rename internal/webui/dist/assets/{nginx-CION907h.js => nginx-CE8daTSk.js} (99%) rename internal/webui/dist/assets/{nim-Dzpio92F.js => nim-C90aJxat.js} (98%) rename internal/webui/dist/assets/{org-BvC1nNcX.js => org-BWWOHulA.js} (96%) rename internal/webui/dist/assets/{perl-FWmJiLAv.js => perl-DzXlbSFI.js} (99%) rename internal/webui/dist/assets/{php-Cs9OQtG7.js => php-B2g8KKRt.js} (99%) rename internal/webui/dist/assets/{pug-LuggxQtI.js => pug-BiwjVDkK.js} (99%) rename internal/webui/dist/assets/{qml-cR0dLM4Z.js => qml-DPu7AuZ_.js} (98%) rename internal/webui/dist/assets/{r-D5GoUSdE.js => r-CaZx80xz.js} (99%) rename internal/webui/dist/assets/{razor-CR0Ji7pe.js => razor-BgTeCNoL.js} (99%) rename internal/webui/dist/assets/{regexp-C6xScJlk.js => regexp-CkmzLcBD.js} (99%) rename internal/webui/dist/assets/{rst-CF6V6ePx.js => rst-BetBoc7w.js} (96%) rename internal/webui/dist/assets/{ruby-R3F_6Mdo.js => ruby-iZlDYJk9.js} (98%) rename internal/webui/dist/assets/{sas-zH5LzPCf.js => sas-Bw60vxj-.js} (99%) rename internal/webui/dist/assets/{scss-ZEAZglbY.js => scss-f6sjw7k_.js} (99%) rename internal/webui/dist/assets/{shellscript-B8ftsUqb.js => shellscript-BL3fFvD_.js} (99%) rename internal/webui/dist/assets/{shellsession-P069U12g.js => shellsession-CC2I9JKe.js} (91%) rename internal/webui/dist/assets/{soy-CKoWzens.js => soy-DKAl9I0F.js} (99%) rename internal/webui/dist/assets/{sql-QEMNPZ4T.js => sql-IaP04OFe.js} (99%) rename internal/webui/dist/assets/{stata-BiTjf37T.js => stata-Dv_6cn9o.js} (99%) rename internal/webui/dist/assets/{surrealql-Wm_CIXs5.js => surrealql-DmbcuQy8.js} (99%) rename internal/webui/dist/assets/{svelte-0pmI4uLE.js => svelte-uMxbmgXS.js} (99%) rename internal/webui/dist/assets/{templ--PeeJH2H.js => templ-B78ksfer.js} (99%) rename internal/webui/dist/assets/{tex-DaemZuNL.js => tex-CaGRzAG_.js} (98%) rename internal/webui/dist/assets/{ts-tags-BQ15nl3d.js => ts-tags-CNYG2Eot.js} (98%) rename internal/webui/dist/assets/{tsx-D7VJyEh5.js => tsx-C-FjrBVW.js} (99%) rename internal/webui/dist/assets/{twig-CL7zAR6w.js => twig-8BdDMjEc.js} (98%) rename internal/webui/dist/assets/{typescript-B0CFpljX.js => typescript-CRJ68kce.js} (99%) rename internal/webui/dist/assets/{typst-BREik9O1.js => typst-B0KuliC2.js} (99%) rename internal/webui/dist/assets/{vue-CGCjzvrH.js => vue-BwtkPb4P.js} (98%) rename internal/webui/dist/assets/{vue-html-Bx0Y_gr3.js => vue-html-DuI7L0W7.js} (99%) rename internal/webui/dist/assets/{vue-vine-7Ywe39of.js => vue-vine-Du2VWbMb.js} (99%) rename internal/webui/dist/assets/{xml-KmXNDLBK.js => xml-DDJpq1Oa.js} (97%) rename internal/webui/dist/assets/{xsl-HCdC-ABc.js => xsl-Bop51BZ5.js} (95%) rename internal/webui/dist/assets/{yaml-BIsyNzg5.js => yaml-CnVvXmYQ.js} (99%) diff --git a/DESIGN.md b/DESIGN.md index 7cf2f352..eed3a0ae 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -416,6 +416,9 @@ Do not add motion for decoration. New animation must honor File/folder rows, filter, summary toggle, and review progress retain desktop control heights and spacing; do not apply the general mobile enlargement here. - Hide redundant summary/shortcut detail before removing essential actions. + Keep the Files changed total and inline added/deleted/modified/renamed counts + visible in the drawer. Use file icons, semantic status colors, hover labels, + and accessible names; wrap the group when the sidebar is too narrow. - At mobile widths or coarse pointers, app-owned controls target 44px hit heights; icon controls also reach 44px width. Text-input sizing uses `--text-input-touch`. The compact View options and collapse/expand icons match the theme control's diff --git a/apps/web/src/ReviewTools.tsx b/apps/web/src/ReviewTools.tsx index 16891e0f..e9294b90 100644 --- a/apps/web/src/ReviewTools.tsx +++ b/apps/web/src/ReviewTools.tsx @@ -1,4 +1,11 @@ -import { ChevronDownIcon, CopyIcon } from "lucide-react"; +import { + ChevronDownIcon, + CopyIcon, + FileMinus2Icon, + FilePenLineIcon, + FilePlus2Icon, + FileSymlinkIcon, +} from "lucide-react"; import { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { @@ -145,6 +152,34 @@ export function ChangeSummary() { save("summary-collapsed", String(summaryCollapsed)); }, [summaryCollapsed]); const allFiles = repository?.files ?? []; + const fileChanges = [ + { + kind: "added", + Icon: FilePlus2Icon, + count: allFiles.filter((file) => ["A", "?", "C"].includes(file.status)) + .length, + description: "Files added (including untracked and copied files)", + }, + { + kind: "deleted", + Icon: FileMinus2Icon, + count: allFiles.filter((file) => file.status === "D").length, + description: "Files deleted", + }, + { + kind: "modified", + Icon: FilePenLineIcon, + count: allFiles.filter((file) => ["M", "T", "U"].includes(file.status)) + .length, + description: "Files modified (including type changes and conflicts)", + }, + { + kind: "renamed", + Icon: FileSymlinkIcon, + count: allFiles.filter((file) => file.status === "R").length, + description: "Files renamed", + }, + ]; const additions = allFiles.reduce((sum, file) => sum + file.additions, 0); const deletions = allFiles.reduce((sum, file) => sum + file.deletions, 0); const reviewedCount = allFiles.filter(isReviewed).length; @@ -166,9 +201,30 @@ export function ChangeSummary() {