Skip to content

Commit

Permalink
Foundations for the budget automations UI (#4308)
Browse files Browse the repository at this point in the history
* Foundations for the budget automations UI

* Coderabbit
  • Loading branch information
jfdoming authored Feb 19, 2025
1 parent df9e6ec commit 7c9a499
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 17 deletions.
6 changes: 6 additions & 0 deletions packages/component-library/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,10 @@ export const styles: Record<string, any> = {
lightScrollbar: null as CSSProperties | null,
darkScrollbar: null as CSSProperties | null,
scrollbarWidth: null as number | null,
editorPill: {
color: theme.pillText,
backgroundColor: theme.pillBackground,
borderRadius: 4,
padding: '3px 5px',
},
};
14 changes: 14 additions & 0 deletions packages/desktop-client/src/components/budget/SidebarCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ import {
} from 'loot-core/types/models';

import { useContextMenu } from '../../hooks/useContextMenu';
import { useFeatureFlag } from '../../hooks/useFeatureFlag';
import { SvgCheveronDown } from '../../icons/v1';
import { theme } from '../../style';
import { NotesButton } from '../NotesButton';
import { InputCell } from '../table';

import { CategoryAutomationButton } from './goals/CategoryAutomationButton';

type SidebarCategoryProps = {
innerRef: Ref<HTMLDivElement>;
category: CategoryEntity;
categoryGroup?: CategoryGroupEntity;
dragPreview?: boolean;
dragging?: boolean;
editing: boolean;
goalsShown?: boolean;
style?: CSSProperties;
borderColor?: string;
isLast?: boolean;
Expand All @@ -41,6 +45,7 @@ export function SidebarCategory({
dragPreview,
dragging,
editing,
goalsShown = false,
style,
isLast,
onEditName,
Expand All @@ -49,6 +54,7 @@ export function SidebarCategory({
onHideNewCategory,
}: SidebarCategoryProps) {
const { t } = useTranslation();
const goalTemplatesUIEnabled = useFeatureFlag('goalTemplatesUIEnabled');

const temporary = category.id === 'new';
const { setMenuOpen, menuOpen, handleContextMenu, resetPosition, position } =
Expand Down Expand Up @@ -129,6 +135,14 @@ export function SidebarCategory({
</Popover>
</View>
<View style={{ flex: 1 }} />
{!goalsShown && goalTemplatesUIEnabled && (
<View style={{ flexShrink: 0 }}>
<CategoryAutomationButton
style={dragging && { color: 'currentColor' }}
defaultColor={theme.pageTextLight}
/>
</View>
)}
<View style={{ flexShrink: 0 }}>
<NotesButton
id={category.id}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { type CSSProperties } from 'react';

import { Button } from '@actual-app/components/button';
import { theme } from '@actual-app/components/theme';

import { pushModal } from 'loot-core/client/actions';
import { type Template } from 'loot-core/server/budget/types/templates';

import { useFeatureFlag } from '../../../hooks/useFeatureFlag';
import { SvgChartPie } from '../../../icons/v1';
import { useDispatch } from '../../../redux';

type CategoryAutomationButtonProps = {
width?: number;
height?: number;
defaultColor?: string;
style?: CSSProperties;
};
export function CategoryAutomationButton({
width = 12,
height = 12,
defaultColor = theme.buttonNormalText,
style,
}: CategoryAutomationButtonProps) {
const automations: Template[] = [];
const hasAutomations = !!automations.length;

const dispatch = useDispatch();

const goalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled');
const goalTemplatesUIEnabled = useFeatureFlag('goalTemplatesUIEnabled');

if (!goalTemplatesEnabled || !goalTemplatesUIEnabled) {
return null;
}

return (
<Button
variant="bare"
aria-label="Change category automations"
className={!hasAutomations ? 'hover-visible' : ''}
style={{
color: defaultColor,
...style,
...(hasAutomations && { display: 'flex !important' }),
}}
onPress={() => {
dispatch(pushModal('category-automations-edit'));
}}
>
<SvgChartPie style={{ width, height, flexShrink: 0 }} />
</Button>
);
}
19 changes: 3 additions & 16 deletions packages/desktop-client/src/components/modals/EditRuleModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,7 @@ function FieldError({ type }) {
function Editor({ error, style, children }) {
return (
<View style={style} data-testid="editor-row">
<Stack
direction="row"
align="center"
spacing={1}
style={{
padding: '3px 5px',
}}
>
<Stack direction="row" align="center" spacing={1}>
{children}
</Stack>
{error && <FieldError type={error} />}
Expand Down Expand Up @@ -1009,12 +1002,6 @@ export function EditRuleModal({ defaultRule, onSave: originalOnSave }) {
}
}

const editorStyle = {
color: theme.pillText,
backgroundColor: theme.pillBackground,
borderRadius: 4,
};

// Enable editing existing split rules even if the feature has since been disabled.
const showSplitButton = actionSplits.length > 0;

Expand Down Expand Up @@ -1105,7 +1092,7 @@ export function EditRuleModal({ defaultRule, onSave: originalOnSave }) {
<ConditionsList
conditionsOp={conditionsOp}
conditions={conditions}
editorStyle={editorStyle}
editorStyle={styles.editorPill}
isSchedule={isSchedule}
onChangeConditions={conds => setConditions(conds)}
/>
Expand Down Expand Up @@ -1186,7 +1173,7 @@ export function EditRuleModal({ defaultRule, onSave: originalOnSave }) {
'append-notes',
]}
action={action}
editorStyle={editorStyle}
editorStyle={styles.editorPill}
onChange={(name, value) => {
onChangeAction(action, name, value);
}}
Expand Down
14 changes: 14 additions & 0 deletions packages/desktop-client/src/components/settings/Experimental.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ function FeatureToggle({
export function ExperimentalFeatures() {
const [expanded, setExpanded] = useState(false);

const goalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled');
const goalTemplatesUIEnabled = useFeatureFlag('goalTemplatesUIEnabled');
const showGoalTemplatesUI =
goalTemplatesUIEnabled ||
(goalTemplatesEnabled &&
localStorage.getItem('devEnableGoalTemplatesUI') === 'true');

return (
<Setting
primaryAction={
Expand All @@ -79,6 +86,13 @@ export function ExperimentalFeatures() {
<FeatureToggle flag="goalTemplatesEnabled">
<Trans>Goal templates</Trans>
</FeatureToggle>
{showGoalTemplatesUI && (
<View style={{ paddingLeft: 22 }}>
<FeatureToggle flag="goalTemplatesUIEnabled">
<Trans>Subfeature: Budget automations UI</Trans>
</FeatureToggle>
</View>
)}
<FeatureToggle
flag="actionTemplating"
feedbackLink="https://github.com/actualbudget/actual/issues/3606"
Expand Down
1 change: 1 addition & 0 deletions packages/desktop-client/src/hooks/useFeatureFlag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useSyncedPref } from './useSyncedPref';

const DEFAULT_FEATURE_FLAG_STATE: Record<FeatureFlag, boolean> = {
goalTemplatesEnabled: false,
goalTemplatesUIEnabled: false,
actionTemplating: false,
contextMenus: false,
openidAuth: false,
Expand Down
1 change: 1 addition & 0 deletions packages/loot-core/src/client/data-hooks/schedules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export function useSchedules({
setError(undefined);

if (!query) {
console.error('No query provided to useSchedules');
return;
}

Expand Down
1 change: 1 addition & 0 deletions packages/loot-core/src/client/state-types/modals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ type FinanceModals = {
};
'keyboard-shortcuts': EmptyObject;
'goal-templates': EmptyObject;
'category-automations-edit': EmptyObject;
};

export type PushModalAction = {
Expand Down
2 changes: 1 addition & 1 deletion packages/loot-core/src/server/budget/types/templates.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ interface AverageTemplate extends BaseTemplate {
}

interface GoalTemplate extends BaseTemplate {
type: 'simple';
type: 'goal';
amount: number;
}

Expand Down
1 change: 1 addition & 0 deletions packages/loot-core/src/types/prefs.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type FeatureFlag =
| 'goalTemplatesEnabled'
| 'goalTemplatesUIEnabled'
| 'actionTemplating'
| 'contextMenus'
| 'openidAuth';
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/4308.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Features
authors: [jfdoming]
---

Foundations for the budget automations UI

0 comments on commit 7c9a499

Please sign in to comment.