Files
backnotprop__plannotator/packages/review-editor/components/PanelViewToggle.tsx
Michael Ramos eb34960da9 fix(review): remember the last-used panel view; full-width toggle and cleaner panel chrome (#1273)
* fix(review): remember the last-used panel view across sessions

- Add cookie-only reviewPanelViewLastUsed config (sections | tree, never
  commits); the header toggle records it and new sessions resolve
  session state, then last-used, then the persisted reviewPanelView.
  Explicit Settings/setup-dialog writes through the reviewView setters
  sync last-used so a stale memo cannot shadow them.
- Wire the FileTree fallback PanelViewToggle to the real panel-view
  selection and route Tree clicks through the shared select funnel
  instead of rendering a hardcoded, no-op tree segment.
- Mark the review-setup-seen cookie when the first-run reset runs, not
  only on the Got it click, so closing the tab without dismissing no
  longer re-stomps preferences every session.

* fix(review): full-width panel toggle, relocated tree controls, click-to-copy diff count

- Give the Git status | Tree | Commits toggle the entire top row in all
  three left panels; segments stretch to fill the row width.
- Move the controls that shared that row (staged count, search,
  collapse-all, hide-viewed, viewed counter) into a shared
  PanelControlsRow rendered below the All files entry, directly above
  the file list; the Commits panel's loaded-commit count moves to its
  own sub-row.
- Replace the footer Copy button with the diff count itself as the copy
  trigger (shared CopyDiffFooter): a keyboard-reachable button with the
  "click to copy the entire diff set" tooltip and transient
  Copied/Failed feedback in the old button's slot.
- Add a tooltip to the file-row stage button using the same Tooltip
  mechanism as the viewed control ("Stage file (git add)").

* fix(review): put Tree first in the panel view toggle

* fix(review): resolve effective panel view for the toggle; keep self-heal off the last-used memo

- Add resolvePanelView() and pass the EFFECTIVE view to FileTree so a
  latent sections/commits selection the session cannot offer highlights
  Tree instead of a hidden or wrong segment; allFilesOrder reuses it.
  Unit test covers the no-segment and wrong-segment cases.
- setReviewPanelView() gains { recordLastUsed?: boolean } (default
  true); the App self-heal passes false so repairing a conflicted
  persisted pair no longer overwrites the user's last-used memo.
- Update the AGENTS.md since-base section to the new toggle semantics
  (last-used memo, resolution order, setter sync, one-time first-run).
- Hardening: fold the diff counts into the copy button's aria-label,
  skip the tooltip while the copy button is disabled (hover never fires
  on a disabled native button in several browsers), let toggle segments
  shrink (min-w-0 + truncate), and rework the config test onto a fresh
  ConfigStoreForTest instead of resolving the singleton against a
  throwaway backend.
2026-08-11 23:54:22 -07:00

42 lines
1.7 KiB
TypeScript

import React from 'react';
export type ReviewPanelView = 'sections' | 'commits' | 'tree';
/**
* View switcher for the left review panel — Git status ⇄ Commits ⇄ Tree.
* Rendered as the full-width top row in every view (nothing else shares the
* row) so the control never moves under the user. Segments a session can't
* offer (e.g. Git status on a repo with no resolvable base, Commits outside
* a plain git session) are omitted rather than disabled; Tree is always
* available.
*/
export const PanelViewToggle: React.FC<{
view: ReviewPanelView;
onSelect: (view: ReviewPanelView) => void;
/** Offer the Git status segment (default true). */
showSections?: boolean;
/** Offer the Commits segment (default false — git-local sessions opt in). */
showCommits?: boolean;
}> = ({ view, onSelect, showSections = true, showCommits = false }) => {
const segment = (key: ReviewPanelView, label: string, title: string) => (
<button
onClick={() => onSelect(key)}
className={`flex-1 min-w-0 truncate px-1 py-0.5 rounded-sm text-xs leading-none whitespace-nowrap text-center transition-colors ${
view === key ? 'bg-background text-foreground shadow-sm font-medium' : 'text-muted-foreground hover:text-foreground'
}`}
title={title}
aria-pressed={view === key}
>
{label}
</button>
);
return (
<div className="flex w-full items-center bg-muted/50 rounded p-0.5" role="group" aria-label="Panel view">
{segment('tree', 'Tree', 'Tree view')}
{showSections && segment('sections', 'Git status', 'Git status view (Committed / Changes / Untracked)')}
{showCommits && segment('commits', 'Commits', 'Commit history — click a commit to review its diff')}
</div>
);
};