-
Notifications
You must be signed in to change notification settings - Fork 487
feat(ui): add backlog pagination and hide feature for suggestions #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ui): add backlog pagination and hide feature for suggestions #227
Conversation
- Add hide button on backlog cards to hide unwanted suggestions - Hidden features get dimmed visual appearance (opacity + grayscale) - Add filter mode: click EyeOff icon to show ONLY hidden features - Add backlog pagination: shows 10 items with "+10" and "All" buttons - Add sticky compact bar that appears on scroll, resets pagination 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughThis PR adds feature-hiding functionality with backlog pagination controls. Changes include toggling feature visibility via a hide action, dimming hidden cards visually, introducing backlog pagination with show/hide filtering, adding a compact scroll bar to columns, and extending the Feature type with a hidden field. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant CardActions
participant useBoardActions
participant updateFeature as Feature State
participant persistFeatureUpdate as Persistence
participant UI as KanbanCard UI
User->>CardActions: Click Hide Button (onHide)
CardActions->>useBoardActions: handleHideFeature(feature)
rect rgb(200, 220, 240)
Note over useBoardActions,updateFeature: Update State
useBoardActions->>updateFeature: Toggle feature.hidden flag
end
rect rgb(200, 240, 220)
Note over useBoardActions,persistFeatureUpdate: Persist Changes
useBoardActions->>persistFeatureUpdate: persistFeatureUpdate(feature)
persistFeatureUpdate-->>useBoardActions: ✓ Saved
end
rect rgb(240, 220, 200)
Note over useBoardActions,UI: Reflect in UI
useBoardActions->>UI: Re-render with hidden=true
UI->>UI: Apply dimming classes<br/>(opacity-40, grayscale)
UI-->>User: Card appears dimmed
end
useBoardActions->>User: Show toast notification
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The changes introduce cohesive feature-hiding and backlog pagination capabilities across multiple layers (hooks, components, types). While several files are affected with new props and state management, the modifications follow consistent patterns (prop drilling, state exposure) and the logic remains straightforward. Primary focus areas include verifying hook integration, prop propagation correctness, and hidden-state UI rendering consistency. Possibly related PRs
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Summary of ChangesHello @Daniel-Lundqvist, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the user experience for managing large backlogs, particularly those generated by AI. It introduces a "hide" functionality for individual suggestions, allowing users to temporarily remove unwanted items without permanent deletion. Furthermore, it implements pagination to prevent overwhelming lists and adds a "Compact" bar for improved navigation, making the backlog more manageable and efficient to use. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces some excellent new features for managing the backlog, including pagination, hiding features, and a compact navigation bar. The code is well-structured, and the use of custom hooks to encapsulate complex logic is great. I've provided a few suggestions to enhance code clarity, improve performance, and ensure UI consistency. Overall, this is a solid contribution that will significantly improve the user experience for projects with many suggestions.
| data-testid={`hide-${feature.id}`} | ||
| title={feature.hidden ? 'Show' : 'Hide'} | ||
| > | ||
| <EyeOff className="w-3 h-3" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The icon for the hide/show button is static and always shows EyeOff. This can be confusing for the user. When the feature is hidden, the button's title is 'Show', so the icon should be Eye to represent the action of showing. When the feature is visible, the title is 'Hide', and the EyeOff icon is appropriate.
Consider making the icon dynamic based on the feature.hidden state to improve user experience. This would also make it consistent with the hide/show toggle in the backlog header.
| <EyeOff className="w-3 h-3" /> | |
| {feature.hidden ? <Eye className="w-3 h-3" /> : <EyeOff className="w-3 h-3" />} |
|
|
||
| const handleScroll = () => { | ||
| // Show compact bar when scrolled more than 100px | ||
| setShowCompactBar(container.scrollTop > 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scroll threshold 100 is a magic number. It's better to define it as a constant at the top of the file or component for better readability and maintainability. For example:
const COMPACT_BAR_SCROLL_THRESHOLD_PX = 100;Then use this constant here.
| setShowCompactBar(container.scrollTop > 100); | |
| setShowCompactBar(container.scrollTop > COMPACT_BAR_SCROLL_THRESHOLD_PX); |
| const getColumnFeatures = useCallback( | ||
| (columnId: ColumnId) => { | ||
| return columnFeaturesMap[columnId]; | ||
| const allFeatures = columnFeaturesMap[columnId]; | ||
| // Apply pagination and hidden filter only to backlog column | ||
| if (columnId === 'backlog') { | ||
| // If showing only hidden, filter to just hidden features | ||
| if (showOnlyHidden) { | ||
| return allFeatures.filter((f) => f.hidden); | ||
| } | ||
| // Otherwise, show non-hidden features with pagination | ||
| const nonHiddenFeatures = allFeatures.filter((f) => !f.hidden); | ||
| return nonHiddenFeatures.slice(0, backlogVisibleCount); | ||
| } | ||
| return allFeatures; | ||
| }, | ||
| [columnFeaturesMap] | ||
| [columnFeaturesMap, backlogVisibleCount, showOnlyHidden] | ||
| ); | ||
|
|
||
| // Count hidden features in backlog | ||
| const hiddenFeaturesCount = useMemo(() => { | ||
| return columnFeaturesMap.backlog.filter((f) => f.hidden).length; | ||
| }, [columnFeaturesMap.backlog]); | ||
|
|
||
| // Calculate backlog pagination info (based on non-hidden features when not in hidden filter mode) | ||
| const backlogPagination = useMemo(() => { | ||
| const nonHiddenFeatures = columnFeaturesMap.backlog.filter((f) => !f.hidden); | ||
| const totalCount = showOnlyHidden ? hiddenFeaturesCount : nonHiddenFeatures.length; | ||
| const visibleCount = showOnlyHidden | ||
| ? hiddenFeaturesCount | ||
| : Math.min(backlogVisibleCount, totalCount); | ||
| const hasMore = !showOnlyHidden && visibleCount < totalCount; | ||
| const remainingCount = totalCount - visibleCount; | ||
| return { | ||
| totalCount, | ||
| visibleCount, | ||
| hasMore, | ||
| remainingCount, | ||
| hiddenCount: hiddenFeaturesCount, | ||
| showOnlyHidden, | ||
| }; | ||
| }, [columnFeaturesMap.backlog, backlogVisibleCount, hiddenFeaturesCount, showOnlyHidden]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are multiple places where columnFeaturesMap.backlog is filtered to separate hidden and non-hidden features (getColumnFeatures, hiddenFeaturesCount, backlogPagination). This is inefficient as it performs the same filtering operation multiple times on every render.
To improve performance and code clarity, you can memoize the filtered lists of hidden and non-hidden features once, and then reuse these lists in the other hooks. This avoids redundant computations.
const { nonHiddenFeatures, hiddenFeatures } = useMemo(() => {
const hidden: Feature[] = [];
const nonHidden: Feature[] = [];
for (const f of columnFeaturesMap.backlog) {
if (f.hidden) {
hidden.push(f);
} else {
nonHidden.push(f);
}
}
return { nonHiddenFeatures: nonHidden, hiddenFeatures: hidden };
}, [columnFeaturesMap.backlog]);
const getColumnFeatures = useCallback(
(columnId: ColumnId) => {
// Apply pagination and hidden filter only to backlog column
if (columnId === 'backlog') {
// If showing only hidden, filter to just hidden features
if (showOnlyHidden) {
return hiddenFeatures;
}
// Otherwise, show non-hidden features with pagination
return nonHiddenFeatures.slice(0, backlogVisibleCount);
}
return columnFeaturesMap[columnId];
},
[columnFeaturesMap, backlogVisibleCount, showOnlyHidden, nonHiddenFeatures, hiddenFeatures]
);
// Count hidden features in backlog
const hiddenFeaturesCount = hiddenFeatures.length;
// Calculate backlog pagination info (based on non-hidden features when not in hidden filter mode)
const backlogPagination = useMemo(() => {
const totalCount = showOnlyHidden ? hiddenFeaturesCount : nonHiddenFeatures.length;
const visibleCount = showOnlyHidden
? hiddenFeaturesCount
: Math.min(backlogVisibleCount, totalCount);
const hasMore = !showOnlyHidden && visibleCount < totalCount;
const remainingCount = totalCount - visibleCount;
return {
totalCount,
visibleCount,
hasMore,
remainingCount,
hiddenCount: hiddenFeaturesCount,
showOnlyHidden,
};
}, [nonHiddenFeatures, backlogVisibleCount, hiddenFeaturesCount, showOnlyHidden]);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx (1)
304-319: Consider toggling the icon based on hidden state for better visual feedback.The button title correctly changes between "Show" and "Hide" based on
feature.hidden, but the icon always showsEyeOff. For better UX, consider usingEyewhen the feature is hidden (to indicate "show") andEyeOffwhen visible (to indicate "hide").🔎 Proposed fix
+import { + ... + Eye, + EyeOff, +} from 'lucide-react'; ... {onHide && ( <Button variant="outline" size="sm" className="h-7 text-xs px-2" onClick={(e) => { e.stopPropagation(); onHide(); }} onPointerDown={(e) => e.stopPropagation()} data-testid={`hide-${feature.id}`} title={feature.hidden ? 'Show' : 'Hide'} > - <EyeOff className="w-3 h-3" /> + {feature.hidden ? <Eye className="w-3 h-3" /> : <EyeOff className="w-3 h-3" />} </Button> )}apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts (2)
27-30: Consider resetting pagination when search query changes.The
backlogVisibleCountstate persists whensearchQuerychanges. If a user expands to show 50 items, then filters by search, they might see unexpected results. Consider adding auseEffectto reset pagination when relevant dependencies change.🔎 Proposed fix
+import { useMemo, useCallback, useState, useEffect } from 'react'; ... // State for backlog pagination - how many items to show const [backlogVisibleCount, setBacklogVisibleCount] = useState(BACKLOG_PAGE_SIZE); // State for showing only hidden features (filter mode) const [showOnlyHidden, setShowOnlyHidden] = useState(false); + // Reset pagination when search query changes + useEffect(() => { + setBacklogVisibleCount(BACKLOG_PAGE_SIZE); + }, [searchQuery]);
203-206: Minor: UsingInfinityfor "show all" works but is unconventional.Setting
backlogVisibleCounttoInfinityworks correctly with the slice operation, but it's somewhat unusual. An alternative would be using a very large number or tracking an explicit "show all" boolean flag. This is a minor style preference and the current approach functions correctly.apps/ui/src/components/views/board-view/kanban-board.tsx (1)
174-209: Consider adding aria-label for better accessibility.The hidden features toggle button has a title attribute, but explicit
aria-labelwould improve screen reader support, especially given the dynamic nature of the title.Suggested accessibility enhancement
<Button variant="ghost" size="sm" className={cn( 'h-6 w-6 p-0 relative', backlogPagination.showOnlyHidden ? 'text-primary hover:text-primary/80 bg-primary/10 hover:bg-primary/20' : 'text-muted-foreground hover:text-foreground hover:bg-muted/50' )} onClick={onToggleShowOnlyHidden} title={ backlogPagination.showOnlyHidden ? 'Show all features' : `Show ${backlogPagination.hiddenCount} hidden feature${backlogPagination.hiddenCount > 1 ? 's' : ''}` } + aria-label={ + backlogPagination.showOnlyHidden + ? 'Show all features' + : `Show ${backlogPagination.hiddenCount} hidden feature${backlogPagination.hiddenCount > 1 ? 's' : ''}` + } data-testid="show-hidden-button" >
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/ui/src/components/views/board-view.tsxapps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsxapps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsxapps/ui/src/components/views/board-view/components/kanban-column.tsxapps/ui/src/components/views/board-view/hooks/use-board-actions.tsapps/ui/src/components/views/board-view/hooks/use-board-column-features.tsapps/ui/src/components/views/board-view/kanban-board.tsxlibs/types/src/feature.ts
🧰 Additional context used
🧬 Code graph analysis (5)
apps/ui/src/components/views/board-view/hooks/use-board-actions.ts (3)
libs/types/src/feature.ts (1)
Feature(24-59)apps/ui/src/store/app-store.ts (1)
Feature(256-272)apps/ui/src/lib/utils.ts (1)
truncateDescription(32-37)
apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx (1)
apps/ui/src/components/ui/button.tsx (1)
Button(108-108)
apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts (1)
libs/types/src/feature.ts (1)
Feature(24-59)
apps/ui/src/components/views/board-view/components/kanban-column.tsx (1)
apps/ui/src/lib/utils.ts (1)
cn(5-7)
apps/ui/src/components/views/board-view/kanban-board.tsx (3)
libs/types/src/feature.ts (1)
Feature(24-59)apps/ui/src/hooks/use-keyboard-shortcuts.ts (1)
useKeyboardShortcutsConfig(241-244)apps/ui/src/lib/utils.ts (1)
cn(5-7)
🔇 Additional comments (16)
libs/types/src/feature.ts (1)
33-33: LGTM!The
hiddenfield addition is clean and backward-compatible. The optional boolean type is appropriate for a toggle state, and the comment accurately documents the intended behavior.apps/ui/src/components/views/board-view/hooks/use-board-actions.ts (1)
862-876: LGTM!The
handleHideFeatureimplementation correctly toggles thehiddenstate, persists updates, and shows appropriate toast notifications. The pattern is consistent with other handlers in this file (e.g.,handleManualVerify,handleCompleteFeature).apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (1)
193-200: LGTM!The hidden card visual treatment is well-implemented with appropriate opacity, grayscale, and hover states that provide good user feedback. The conditional ordering correctly prioritizes
isCurrentAutoTaskoverhiddenstate, which is the expected behavior for running tasks.apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts (2)
127-143: LGTM!The sorting logic correctly categorizes features into visible, blocked, and hidden groups, maintaining the dependency order within each group. The final order (visible → blocked → hidden) aligns with the PR requirements.
156-172: LGTM!The pagination and filter logic is well-structured:
- When
showOnlyHiddenis true, returns all hidden features without pagination (appropriate since users need to manage all hidden items)- When showing normal view, correctly filters out hidden features before applying pagination slice
apps/ui/src/components/views/board-view/kanban-board.tsx (5)
8-17: LGTM! Clean icon and utility imports.The new lucide-react icons and cn utility are correctly imported and will be used for backlog pagination and visibility controls.
53-72: Well-structured backlog pagination API.The new props provide a clean interface for pagination and visibility controls. The backlogPagination object encapsulates all necessary state, and the handler props follow a consistent naming pattern.
133-135: Correct count binding for backlog column.Using
backlogPagination.totalCountfor the backlog column ensures the header displays the total number of items (including hidden ones), which provides users with complete context.
227-252: Clean pagination controls in footer.The "+10" and "All" buttons provide intuitive pagination controls, showing remaining count for context. The conditional rendering based on
hasMoreprevents unnecessary UI clutter.
281-281: Correct propagation of onHide handler.The
onHideprop is properly passed to each KanbanCard instance, enabling the hide feature functionality at the card level.apps/ui/src/components/views/board-view/components/kanban-column.tsx (4)
1-1: LGTM! Clean hook and prop additions.The new React hooks and props are well-typed with helpful JSDoc comments explaining their purpose.
Also applies to: 4-4, 14-14, 20-23
42-57: Excellent scroll tracking implementation.The scroll listener is properly cleaned up, uses passive mode for better performance, and includes appropriate guards. The 100px threshold provides a good balance for triggering the compact bar.
59-64: Clean scroll-to-top implementation.The smooth scroll behavior provides good UX, and the optional chaining on
onCompactadds defensive safety.
139-140: Clean footer action rendering.The conditional rendering and spacing for the footer action are well-implemented.
apps/ui/src/components/views/board-view.tsx (2)
382-382: Correct hook return destructuring.The new hook returns are properly destructured and will be passed to the KanbanBoard component. The naming is consistent with the component's prop interface.
Also applies to: 748-756
1033-1033: Proper integration of backlog pagination and hide feature.All new props are correctly wired to their respective hooks, maintaining consistency with the existing codebase patterns.
Also applies to: 1041-1045
| {/* Compact Bar - appears when scrolled down */} | ||
| {showCompactBar && onCompact && ( | ||
| <div | ||
| className={cn( | ||
| 'sticky top-0 z-20 -mx-2 -mt-2 mb-2 px-3 py-2', | ||
| 'flex items-center justify-center gap-2', | ||
| 'bg-primary/10 backdrop-blur-md', | ||
| 'border-b border-primary/20', | ||
| 'cursor-pointer', | ||
| 'hover:bg-primary/20 transition-colors duration-200', | ||
| 'text-xs font-medium text-primary' | ||
| )} | ||
| onClick={handleCompactClick} | ||
| data-testid="compact-bar" | ||
| > | ||
| <ChevronUp className="w-3.5 h-3.5" /> | ||
| <span>Compact{visibleCount ? ` (${visibleCount})` : ''}</span> | ||
| <ChevronUp className="w-3.5 h-3.5" /> | ||
| </div> | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compact bar needs accessibility improvements.
The compact bar is implemented as a clickable div, which lacks keyboard navigation and proper semantic meaning. This prevents keyboard-only users from accessing the functionality.
Recommended accessibility fix
- {showCompactBar && onCompact && (
- <div
- className={cn(
- 'sticky top-0 z-20 -mx-2 -mt-2 mb-2 px-3 py-2',
- 'flex items-center justify-center gap-2',
- 'bg-primary/10 backdrop-blur-md',
- 'border-b border-primary/20',
- 'cursor-pointer',
- 'hover:bg-primary/20 transition-colors duration-200',
- 'text-xs font-medium text-primary'
- )}
- onClick={handleCompactClick}
- data-testid="compact-bar"
- >
- <ChevronUp className="w-3.5 h-3.5" />
- <span>Compact{visibleCount ? ` (${visibleCount})` : ''}</span>
- <ChevronUp className="w-3.5 h-3.5" />
- </div>
- )}
+ {showCompactBar && onCompact && (
+ <button
+ type="button"
+ className={cn(
+ 'sticky top-0 z-20 -mx-2 -mt-2 mb-2 px-3 py-2 w-[calc(100%+1rem)]',
+ 'flex items-center justify-center gap-2',
+ 'bg-primary/10 backdrop-blur-md',
+ 'border-b border-primary/20',
+ 'cursor-pointer',
+ 'hover:bg-primary/20 transition-colors duration-200',
+ 'text-xs font-medium text-primary'
+ )}
+ onClick={handleCompactClick}
+ aria-label={`Scroll to top and reset view${visibleCount ? ` (showing ${visibleCount})` : ''}`}
+ data-testid="compact-bar"
+ >
+ <ChevronUp className="w-3.5 h-3.5" />
+ <span>Compact{visibleCount ? ` (${visibleCount})` : ''}</span>
+ <ChevronUp className="w-3.5 h-3.5" />
+ </button>
+ )}This makes the compact bar keyboard accessible and provides proper semantic meaning with an aria-label.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {/* Compact Bar - appears when scrolled down */} | |
| {showCompactBar && onCompact && ( | |
| <div | |
| className={cn( | |
| 'sticky top-0 z-20 -mx-2 -mt-2 mb-2 px-3 py-2', | |
| 'flex items-center justify-center gap-2', | |
| 'bg-primary/10 backdrop-blur-md', | |
| 'border-b border-primary/20', | |
| 'cursor-pointer', | |
| 'hover:bg-primary/20 transition-colors duration-200', | |
| 'text-xs font-medium text-primary' | |
| )} | |
| onClick={handleCompactClick} | |
| data-testid="compact-bar" | |
| > | |
| <ChevronUp className="w-3.5 h-3.5" /> | |
| <span>Compact{visibleCount ? ` (${visibleCount})` : ''}</span> | |
| <ChevronUp className="w-3.5 h-3.5" /> | |
| </div> | |
| )} | |
| {/* Compact Bar - appears when scrolled down */} | |
| {showCompactBar && onCompact && ( | |
| <button | |
| type="button" | |
| className={cn( | |
| 'sticky top-0 z-20 -mx-2 -mt-2 mb-2 px-3 py-2 w-[calc(100%+1rem)]', | |
| 'flex items-center justify-center gap-2', | |
| 'bg-primary/10 backdrop-blur-md', | |
| 'border-b border-primary/20', | |
| 'cursor-pointer', | |
| 'hover:bg-primary/20 transition-colors duration-200', | |
| 'text-xs font-medium text-primary' | |
| )} | |
| onClick={handleCompactClick} | |
| aria-label={`Scroll to top and reset view${visibleCount ? ` (showing ${visibleCount})` : ''}`} | |
| data-testid="compact-bar" | |
| > | |
| <ChevronUp className="w-3.5 h-3.5" /> | |
| <span>Compact{visibleCount ? ` (${visibleCount})` : ''}</span> | |
| <ChevronUp className="w-3.5 h-3.5" /> | |
| </button> | |
| )} |
|
please address any major and critical reviews found by th ai reviewers |
|
conflicts and no response from original pr creator, closing for now. |
Summary
Why this matters
When using AI to generate suggestions, backlogs can grow to 100+ items. This makes:
Demo
Hidden cards are visually dimmed (40% opacity + grayscale) to indicate their state. The filter toggle in the header makes it easy to review and unhide features.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.