From 58e6c6f23a995c2b509ce2ae40cfe6d807d5d642 Mon Sep 17 00:00:00 2001
From: dymanoid <9433345+dymanoid@users.noreply.github.com>
Date: Wed, 3 Jul 2024 20:00:03 +0200
Subject: [PATCH] Fix rollover arrow display for mobile and desktop (#2943)

* Fix rollover arrow display for mobile and desktop

* Add release notes

* Implement review suggestions

* Fix rollover indicator without goals
---
 .../budget/BalanceWithCarryover.tsx           | 77 +++++++++++--------
 .../budget/report/ReportComponents.tsx        |  1 -
 .../budget/rollover/RolloverComponents.tsx    |  1 -
 .../components/mobile/budget/BudgetTable.jsx  | 18 +++++
 .../modals/ReportBalanceMenuModal.tsx         | 17 +++-
 .../modals/RolloverBalanceMenuModal.tsx       | 17 +++-
 upcoming-release-notes/2943.md                |  6 ++
 7 files changed, 100 insertions(+), 37 deletions(-)
 create mode 100644 upcoming-release-notes/2943.md

diff --git a/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx b/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx
index c90a255d1..ca816832c 100644
--- a/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx
+++ b/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx
@@ -3,7 +3,6 @@ import React, { type ComponentPropsWithoutRef } from 'react';
 
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
 import { SvgArrowThinRight } from '../../icons/v1';
-import { useResponsive } from '../../ResponsiveProvider';
 import { type CSSProperties } from '../../style';
 import { View } from '../common/View';
 import { type Binding } from '../spreadsheet';
@@ -12,6 +11,10 @@ import { useSheetValue } from '../spreadsheet/useSheetValue';
 
 import { makeBalanceAmountStyle } from './util';
 
+type CarryoverIndicatorProps = {
+  style?: CSSProperties;
+};
+
 type BalanceWithCarryoverProps = Omit<
   ComponentPropsWithoutRef<typeof CellValue>,
   'binding'
@@ -21,15 +24,38 @@ type BalanceWithCarryoverProps = Omit<
   goal: Binding;
   budgeted: Binding;
   disabled?: boolean;
-  carryoverStyle?: CSSProperties;
+  carryoverIndicator?: ({ style }: CarryoverIndicatorProps) => JSX.Element;
 };
+
+export function DefaultCarryoverIndicator({ style }: CarryoverIndicatorProps) {
+  return (
+    <View
+      style={{
+        marginLeft: 2,
+        position: 'absolute',
+        right: '-4px',
+        alignSelf: 'center',
+        top: 0,
+        bottom: 0,
+        ...style,
+      }}
+    >
+      <SvgArrowThinRight
+        width={style?.width || 7}
+        height={style?.height || 7}
+        style={style}
+      />
+    </View>
+  );
+}
+
 export function BalanceWithCarryover({
   carryover,
   balance,
   goal,
   budgeted,
   disabled,
-  carryoverStyle,
+  carryoverIndicator = DefaultCarryoverIndicator,
   ...props
 }: BalanceWithCarryoverProps) {
   const carryoverValue = useSheetValue(carryover);
@@ -37,11 +63,21 @@ export function BalanceWithCarryover({
   const goalValue = useSheetValue(goal);
   const budgetedValue = useSheetValue(budgeted);
   const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled');
-
-  const { isNarrowWidth } = useResponsive();
+  const valueStyle = makeBalanceAmountStyle(
+    balanceValue,
+    isGoalTemplatesEnabled ? goalValue : null,
+    budgetedValue,
+  );
 
   return (
-    <>
+    <span
+      style={{
+        alignItems: 'center',
+        display: 'inline-flex',
+        justifyContent: 'right',
+        maxWidth: '100%',
+      }}
+    >
       <CellValue
         {...props}
         binding={balance}
@@ -54,6 +90,8 @@ export function BalanceWithCarryover({
           )
         }
         style={{
+          overflow: 'hidden',
+          textOverflow: 'ellipsis',
           textAlign: 'right',
           ...(!disabled && {
             cursor: 'pointer',
@@ -61,30 +99,7 @@ export function BalanceWithCarryover({
           ...props.style,
         }}
       />
-      {carryoverValue && (
-        <View
-          style={{
-            alignSelf: 'center',
-            marginLeft: 2,
-            position: 'absolute',
-            right: isNarrowWidth ? '-8px' : '-4px',
-            top: 0,
-            bottom: 0,
-            justifyContent: 'center',
-            ...carryoverStyle,
-          }}
-        >
-          <SvgArrowThinRight
-            width={carryoverStyle?.width || 7}
-            height={carryoverStyle?.height || 7}
-            style={makeBalanceAmountStyle(
-              balanceValue,
-              isGoalTemplatesEnabled ? goalValue : null,
-              budgetedValue,
-            )}
-          />
-        </View>
-      )}
-    </>
+      {carryoverValue && carryoverIndicator({ style: valueStyle })}
+    </span>
   );
 }
diff --git a/packages/desktop-client/src/components/budget/report/ReportComponents.tsx b/packages/desktop-client/src/components/budget/report/ReportComponents.tsx
index eabfebb1e..00f2c6c5f 100644
--- a/packages/desktop-client/src/components/budget/report/ReportComponents.tsx
+++ b/packages/desktop-client/src/components/budget/report/ReportComponents.tsx
@@ -321,7 +321,6 @@ export const CategoryMonth = memo(function CategoryMonth({
       {!category.is_income && (
         <Field
           name="balance"
-          truncate={false}
           width="flex"
           style={{ paddingRight: styles.monthRightPadding, textAlign: 'right' }}
         >
diff --git a/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx b/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx
index f24cea5af..28f2553fe 100644
--- a/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx
+++ b/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx
@@ -310,7 +310,6 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
       </Field>
       <Field
         name="balance"
-        truncate={false}
         width="flex"
         style={{ paddingRight: styles.monthRightPadding, textAlign: 'right' }}
       >
diff --git a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
index 73be166ac..5088f1ec2 100644
--- a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
+++ b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
@@ -16,6 +16,7 @@ import { SvgExpandArrow } from '../../../icons/v0';
 import {
   SvgArrowThinLeft,
   SvgArrowThinRight,
+  SvgArrowThickRight,
   SvgCheveronRight,
 } from '../../../icons/v1';
 import { SvgViewShow } from '../../../icons/v2';
@@ -594,6 +595,23 @@ const ExpenseCategory = memo(function ExpenseCategory({
                   </AutoTextSize>
                 </Button>
               )}
+              carryoverIndicator={({ style }) => (
+                <View
+                  style={{
+                    position: 'absolute',
+                    right: '-3px',
+                    top: '-5px',
+                    borderRadius: '50%',
+                    backgroundColor: style?.color ?? theme.pillText,
+                  }}
+                >
+                  <SvgArrowThickRight
+                    width={11}
+                    height={11}
+                    style={{ color: theme.pillBackgroundLight }}
+                  />
+                </View>
+              )}
             />
           </span>
         </View>
diff --git a/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx b/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
index 681e3b1eb..9b6246534 100644
--- a/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
@@ -4,7 +4,10 @@ import { reportBudget } from 'loot-core/client/queries';
 
 import { useCategory } from '../../hooks/useCategory';
 import { type CSSProperties, theme, styles } from '../../style';
-import { BalanceWithCarryover } from '../budget/BalanceWithCarryover';
+import {
+  BalanceWithCarryover,
+  DefaultCarryoverIndicator,
+} from '../budget/BalanceWithCarryover';
 import { BalanceMenu } from '../budget/report/BalanceMenu';
 import { Modal, ModalTitle } from '../common/Modal';
 import { Text } from '../common/Text';
@@ -63,11 +66,21 @@ export function ReportBalanceMenuModal({
             textAlign: 'center',
             ...styles.veryLargeText,
           }}
-          carryoverStyle={{ right: -20, width: 15, height: 15 }}
           carryover={reportBudget.catCarryover(categoryId)}
           balance={reportBudget.catBalance(categoryId)}
           goal={reportBudget.catGoal(categoryId)}
           budgeted={reportBudget.catBudgeted(categoryId)}
+          carryoverIndicator={({ style }) =>
+            DefaultCarryoverIndicator({
+              style: {
+                width: 15,
+                height: 15,
+                display: 'inline-flex',
+                position: 'relative',
+                ...style,
+              },
+            })
+          }
         />
       </View>
       <BalanceMenu
diff --git a/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx b/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
index 4132d2eea..29a4ea856 100644
--- a/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
@@ -4,7 +4,10 @@ import { rolloverBudget } from 'loot-core/client/queries';
 
 import { useCategory } from '../../hooks/useCategory';
 import { type CSSProperties, theme, styles } from '../../style';
-import { BalanceWithCarryover } from '../budget/BalanceWithCarryover';
+import {
+  BalanceWithCarryover,
+  DefaultCarryoverIndicator,
+} from '../budget/BalanceWithCarryover';
 import { BalanceMenu } from '../budget/rollover/BalanceMenu';
 import { Modal, ModalTitle } from '../common/Modal';
 import { Text } from '../common/Text';
@@ -65,11 +68,21 @@ export function RolloverBalanceMenuModal({
             textAlign: 'center',
             ...styles.veryLargeText,
           }}
-          carryoverStyle={{ right: -20, width: 15, height: 15 }}
           carryover={rolloverBudget.catCarryover(categoryId)}
           balance={rolloverBudget.catBalance(categoryId)}
           goal={rolloverBudget.catGoal(categoryId)}
           budgeted={rolloverBudget.catBudgeted(categoryId)}
+          carryoverIndicator={({ style }) =>
+            DefaultCarryoverIndicator({
+              style: {
+                width: 15,
+                height: 15,
+                display: 'inline-flex',
+                position: 'relative',
+                ...style,
+              },
+            })
+          }
         />
       </View>
       <BalanceMenu
diff --git a/upcoming-release-notes/2943.md b/upcoming-release-notes/2943.md
new file mode 100644
index 000000000..423223ee3
--- /dev/null
+++ b/upcoming-release-notes/2943.md
@@ -0,0 +1,6 @@
+---
+category: Bugfix
+authors: [dymanoid]
+---
+
+Fix the carryover arrow display for mobile and desktop views.
-- 
GitLab