-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Apply Template to All Categories in Group for Mobile #3737
base: master
Are you sure you want to change the base?
Changes from all commits
5b924ac
91abab2
af48d6f
d22b5ef
80d323c
9a9db3c
f2d5792
415577e
597fd9f
3922461
d51746d
e363cb7
5f69d72
2b620e7
8c5bd2b
f8de6e9
d5c05fc
846717c
9d8466e
c88cedf
c3286d1
6501668
24fa59f
5b7f9d1
61d11a5
2459aaf
9e7e11c
2cb361a
871fcdf
22d7e0d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,46 @@ | ||||||||||||||||||||||||||||||||||||||
import React, { type ComponentPropsWithoutRef } from 'react'; | ||||||||||||||||||||||||||||||||||||||
import { useTranslation } from 'react-i18next'; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
import { useFeatureFlag } from '../../../hooks/useFeatureFlag'; | ||||||||||||||||||||||||||||||||||||||
import { Menu } from '../../common/Menu'; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
type BudgetMenuGroupProps = Omit< | ||||||||||||||||||||||||||||||||||||||
ComponentPropsWithoutRef<typeof Menu>, | ||||||||||||||||||||||||||||||||||||||
'onMenuSelect' | 'items' | ||||||||||||||||||||||||||||||||||||||
> & { | ||||||||||||||||||||||||||||||||||||||
onApplyGroupTemplate: () => void; | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
export function BudgetMenuGroup({ | ||||||||||||||||||||||||||||||||||||||
onApplyGroupTemplate, | ||||||||||||||||||||||||||||||||||||||
...props | ||||||||||||||||||||||||||||||||||||||
}: BudgetMenuGroupProps) { | ||||||||||||||||||||||||||||||||||||||
const { t } = useTranslation(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); | ||||||||||||||||||||||||||||||||||||||
const onMenuSelect = (name: string) => { | ||||||||||||||||||||||||||||||||||||||
switch (name) { | ||||||||||||||||||||||||||||||||||||||
case 'apply-group-category-template': | ||||||||||||||||||||||||||||||||||||||
onApplyGroupTemplate?.(); | ||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||
throw new Error(`Unrecognized menu item: ${name}`); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+20
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider more graceful error handling in production. The error throwing for unrecognized menu items might be too aggressive for production. Consider logging the error and providing a fallback behavior. const onMenuSelect = (name: string) => {
switch (name) {
case 'apply-group-category-template':
onApplyGroupTemplate?.();
break;
default:
- throw new Error(`Unrecognized menu item: ${name}`);
+ console.error(`Unrecognized menu item: ${name}`);
}
}; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||
<Menu | ||||||||||||||||||||||||||||||||||||||
{...props} | ||||||||||||||||||||||||||||||||||||||
onMenuSelect={onMenuSelect} | ||||||||||||||||||||||||||||||||||||||
items={[ | ||||||||||||||||||||||||||||||||||||||
...(isGoalTemplatesEnabled | ||||||||||||||||||||||||||||||||||||||
? [ | ||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||
name: 'apply-group-category-template', | ||||||||||||||||||||||||||||||||||||||
text: t('Apply budget template'), | ||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||
: []), | ||||||||||||||||||||||||||||||||||||||
]} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+34
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Based on the Menu component implementation and usage context, I can now provide the final response: Consider conditionally rendering the Menu component when empty The Menu component doesn't have built-in handling for empty states, and rendering it with an empty array will result in a clickable menu button that opens an empty menu. To improve the user experience: return isGoalTemplatesEnabled ? (
<Menu
{...props}
onMenuSelect={onMenuSelect}
items={[
{
name: 'apply-group-category-template',
text: t('Apply budget template'),
},
]}
/>
) : null; 🔗 Analysis chainHandle empty menu state when feature is disabled. When
🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if there are other places in the codebase handling empty menus
rg -l "items={(\[\])}" --type ts --type tsx
Length of output: 149 Script: #!/bin/bash
# Search for empty menu items array patterns with proper escaping
rg "items=\{\[\]\}" --type ts --type tsx
# Search for Menu component usage to understand empty state handling
rg -A 3 "<Menu" --type ts --type tsx
# Look for the Menu component definition
ast-grep --pattern 'interface $_Props {
$$$
items: $_
$$$
}'
Length of output: 206 Script: #!/bin/bash
# Search for Menu component usage with correct file extension
rg -A 3 "<Menu" .
# Look for the Menu component definition
rg -A 10 "interface.*Menu.*Props" .
# Search for empty menu items array patterns
rg "items=\{(\[\]|[])" .
Length of output: 17212 Script: #!/bin/bash
# Look for Menu component definition and its props
rg -A 5 "export.*Menu.*=.*" ./packages/desktop-client/src/components/common/Menu.tsx
# Check if there's any handling of empty items
rg -A 5 "items\.length.*===.*0" .
# Look for conditional rendering of Menu component
rg "{\s*items.*length.*[><=].*0.*}" .
Length of output: 963 Script: #!/bin/bash
# Look at the Menu component implementation
cat ./packages/desktop-client/src/components/common/Menu.tsx
# Look for conditional rendering patterns around Menu
rg -B 2 -A 2 "<Menu.*" ./packages/desktop-client/src/components/budget/envelope/BudgetMenuGroup.tsx
Length of output: 6928 |
||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -236,6 +236,7 @@ function BudgetCell({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const categoryNotes = useNotes(category.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const onOpenCategoryBudgetMenu = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log('open'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug logging statement. Debug logging statements should not be committed to production code. - console.log('open'); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dispatch( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pushModal(categoryBudgetMenuModal, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
categoryId: category.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -749,6 +750,7 @@ const ExpenseCategory = memo(function ExpenseCategory({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ExpenseGroupHeader = memo(function ExpenseGroupHeader({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
group, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
month, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
budgeted, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
spent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
balance, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -759,7 +761,26 @@ const ExpenseGroupHeader = memo(function ExpenseGroupHeader({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showBudgetedCol, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
collapsed, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onToggleCollapse, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onBudgetAction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const dispatch = useDispatch(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const onOpenGroupBudgetMenu = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log('OPEN Group header menu' + month); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dispatch( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pushModal('envelope-budget-group-menu', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
month, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
group, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onApplyGroupTemplate: () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onBudgetAction(month, 'apply-multiple-templates', { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
month, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
categories: group.categories | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.filter(c => !c['hidden']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.map(c => c['id']), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+766
to
+783
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clean up the implementation. The function has several issues that should be addressed:
- console.log('OPEN Group header menu' + month);
dispatch(
pushModal('envelope-budget-group-menu', {
month,
group,
onApplyGroupTemplate: () => {
onBudgetAction(month, 'apply-multiple-templates', {
- month,
categories: group.categories
- .filter(c => !c['hidden'])
- .map(c => c['id']),
+ .filter(c => !c.hidden)
+ .map(c => c.id),
});
},
}),
); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const opacity = blank ? 0 : 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const listItemRef = useRef(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const format = useFormat(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -866,24 +887,30 @@ const ExpenseGroupHeader = memo(function ExpenseGroupHeader({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<View | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ ...(!show3Cols && !showBudgetedCol && { display: 'none' }) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CellValue binding={budgeted} type="financial"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{({ type, value }) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<View> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<PrivacyFilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<AutoTextSize | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
key={value} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
as={Text} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
minFontSizePx={6} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
maxFontSizePx={12} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mode="oneline" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={amountStyle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{format(value, type)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</AutoTextSize> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</PrivacyFilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</View> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</CellValue> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variant="bare" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ backgroundColor: 'transparent' }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onPress={() => onOpenGroupBudgetMenu()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CellValue binding={budgeted} type="financial"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{({ type, value }) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<View> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<PrivacyFilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<AutoTextSize | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
key={value} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
as={Text} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
minFontSizePx={6} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
maxFontSizePx={12} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mode="oneline" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={amountStyle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{format(value, type)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</AutoTextSize> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</PrivacyFilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</View> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</CellValue> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</View> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<View | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ ...(!show3Cols && showBudgetedCol && { display: 'none' }) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1016,6 +1043,7 @@ const IncomeGroupHeader = memo(function IncomeGroupHeader({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variant="bare" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paddingRight: 4, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
maxWidth: sidebarColumnWidth, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onPress={() => onEdit?.(group.id)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1320,6 +1348,8 @@ const ExpenseGroup = memo(function ExpenseGroup({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onEdit={onEditGroup} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
collapsed={collapsed} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onToggleCollapse={onToggleCollapse} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
month={month} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onBudgetAction={onBudgetAction} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// onReorderCategory={onReorderCategory} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
🛠️ Refactor suggestion
Consider improving the type definition for better type safety.
The
onApplyGroupTemplate
callback could be enhanced:📝 Committable suggestion