mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-28 01:58:40 -05:00
Fix filtering
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import React, { PureComponent, createRef, useMemo } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Navigate, useParams, useLocation, useMatch } from 'react-router-dom';
|
||||
|
||||
import { debounce } from 'debounce';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { validForTransfer } from 'loot-core/client/transfer';
|
||||
import * as actions from 'loot-core/src/client/actions';
|
||||
import { useFilters } from 'loot-core/src/client/data-hooks/filters';
|
||||
import { SchedulesProvider } from 'loot-core/src/client/data-hooks/schedules';
|
||||
import * as queries from 'loot-core/src/client/queries';
|
||||
@@ -26,6 +24,7 @@ import {
|
||||
import { applyChanges, groupById } from 'loot-core/src/shared/util';
|
||||
|
||||
import { useAccounts } from '../../hooks/useAccounts';
|
||||
import { useActions } from '../../hooks/useActions';
|
||||
import { useCategories } from '../../hooks/useCategories';
|
||||
import { useDateFormat } from '../../hooks/useDateFormat';
|
||||
import { useFailedAccounts } from '../../hooks/useFailedAccounts';
|
||||
@@ -179,7 +178,7 @@ class AccountInternal extends PureComponent {
|
||||
|
||||
this.state = {
|
||||
search: '',
|
||||
filters: props.conditions || [],
|
||||
filterConditions: props.filterConditions || [],
|
||||
loading: true,
|
||||
workingHard: false,
|
||||
reconcileAmount: null,
|
||||
@@ -256,7 +255,7 @@ class AccountInternal extends PureComponent {
|
||||
// Important that any async work happens last so that the
|
||||
// listeners are set up synchronously
|
||||
await this.props.initiallyLoadPayees();
|
||||
await this.fetchTransactions(this.state.filters);
|
||||
await this.fetchTransactions(this.state.filterConditions);
|
||||
|
||||
// If there is a pending undo, apply it immediately (this happens
|
||||
// when an undo changes the location to this page)
|
||||
@@ -285,7 +284,7 @@ class AccountInternal extends PureComponent {
|
||||
|
||||
//Resest sort/filter/search on account change
|
||||
if (this.props.accountId !== prevProps.accountId) {
|
||||
this.setState({ sort: [], search: '', filters: [] });
|
||||
this.setState({ sort: [], search: '', filterConditions: [] });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,10 +312,10 @@ class AccountInternal extends PureComponent {
|
||||
this.paged?.run();
|
||||
};
|
||||
|
||||
fetchTransactions = filters => {
|
||||
fetchTransactions = filterConditions => {
|
||||
const query = this.makeRootQuery();
|
||||
this.rootQuery = this.currentQuery = query;
|
||||
if (filters) this.applyFilters(filters);
|
||||
if (filterConditions) this.applyFilters(filterConditions);
|
||||
else this.updateQuery(query);
|
||||
|
||||
if (this.props.accountId) {
|
||||
@@ -418,7 +417,10 @@ class AccountInternal extends PureComponent {
|
||||
|
||||
onSearchDone = debounce(() => {
|
||||
if (this.state.search === '') {
|
||||
this.updateQuery(this.currentQuery, this.state.filters.length > 0);
|
||||
this.updateQuery(
|
||||
this.currentQuery,
|
||||
this.state.filterConditions.length > 0,
|
||||
);
|
||||
} else {
|
||||
this.updateQuery(
|
||||
queries.makeTransactionSearchQuery(
|
||||
@@ -511,7 +513,7 @@ class AccountInternal extends PureComponent {
|
||||
return (
|
||||
account &&
|
||||
this.state.search === '' &&
|
||||
this.state.filters.length === 0 &&
|
||||
this.state.filterConditions.length === 0 &&
|
||||
(this.state.sort.length === 0 ||
|
||||
(this.state.sort.field === 'date' &&
|
||||
this.state.sort.ascDesc === 'desc'))
|
||||
@@ -599,7 +601,7 @@ class AccountInternal extends PureComponent {
|
||||
{
|
||||
transactions: [],
|
||||
transactionCount: 0,
|
||||
filters: [],
|
||||
filterConditions: [],
|
||||
search: '',
|
||||
sort: [],
|
||||
showBalances: true,
|
||||
@@ -612,9 +614,9 @@ class AccountInternal extends PureComponent {
|
||||
break;
|
||||
case 'remove-sorting': {
|
||||
this.setState({ sort: [] }, () => {
|
||||
const filters = this.state.filters;
|
||||
if (filters.length > 0) {
|
||||
this.applyFilters([...filters]);
|
||||
const filterConditions = this.state.filterConditions;
|
||||
if (filterConditions.length > 0) {
|
||||
this.applyFilters([...filterConditions]);
|
||||
} else {
|
||||
this.fetchTransactions();
|
||||
}
|
||||
@@ -637,12 +639,12 @@ class AccountInternal extends PureComponent {
|
||||
if (this.state.showReconciled) {
|
||||
this.props.savePrefs({ ['hide-reconciled-' + accountId]: true });
|
||||
this.setState({ showReconciled: false }, () =>
|
||||
this.fetchTransactions(this.state.filters),
|
||||
this.fetchTransactions(this.state.filterConditions),
|
||||
);
|
||||
} else {
|
||||
this.props.savePrefs({ ['hide-reconciled-' + accountId]: false });
|
||||
this.setState({ showReconciled: true }, () =>
|
||||
this.fetchTransactions(this.state.filters),
|
||||
this.fetchTransactions(this.state.filterConditions),
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -797,7 +799,7 @@ class AccountInternal extends PureComponent {
|
||||
onShowTransactions = async ids => {
|
||||
this.onApplyFilter({
|
||||
customName: 'Selected transactions',
|
||||
filter: { id: { $oneof: ids } },
|
||||
queryFilter: { id: { $oneof: ids } },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1194,11 +1196,11 @@ class AccountInternal extends PureComponent {
|
||||
|
||||
onReloadSavedFilter = (savedFilter, item) => {
|
||||
if (item === 'reload') {
|
||||
const [getFilter] = this.props.filtersList.filter(
|
||||
const [savedFilter] = this.props.savedFilters.filter(
|
||||
f => f.id === this.state.filterId.id,
|
||||
);
|
||||
this.setState({ conditionsOp: getFilter.conditionsOp });
|
||||
this.applyFilters([...getFilter.conditions]);
|
||||
this.setState({ conditionsOp: savedFilter.conditionsOp });
|
||||
this.applyFilters([...savedFilter.conditions]);
|
||||
} else {
|
||||
if (savedFilter.status) {
|
||||
this.setState({ conditionsOp: savedFilter.conditionsOp });
|
||||
@@ -1217,9 +1219,11 @@ class AccountInternal extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
onUpdateFilter = (oldFilter, updatedFilter) => {
|
||||
onUpdateFilter = (oldCondition, updatedCondition) => {
|
||||
this.applyFilters(
|
||||
this.state.filters.map(f => (f === oldFilter ? updatedFilter : f)),
|
||||
this.state.filterConditions.map(c =>
|
||||
c === oldCondition ? updatedCondition : c,
|
||||
),
|
||||
);
|
||||
this.setState({
|
||||
filterId: {
|
||||
@@ -1232,9 +1236,9 @@ class AccountInternal extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
onDeleteFilter = filter => {
|
||||
this.applyFilters(this.state.filters.filter(f => f !== filter));
|
||||
if (this.state.filters.length === 1) {
|
||||
onDeleteFilter = condition => {
|
||||
this.applyFilters(this.state.filterConditions.filter(c => c !== condition));
|
||||
if (this.state.filterConditions.length === 1) {
|
||||
this.setState({ filterId: [] });
|
||||
this.setState({ conditionsOp: 'and' });
|
||||
} else {
|
||||
@@ -1250,23 +1254,31 @@ class AccountInternal extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
onApplyFilter = async cond => {
|
||||
let filters = this.state.filters;
|
||||
if (cond.customName) {
|
||||
filters = filters.filter(f => f.customName !== cond.customName);
|
||||
onApplyFilter = async conditionOrSavedFilter => {
|
||||
let filterConditions = this.state.filterConditions;
|
||||
if (conditionOrSavedFilter.customName) {
|
||||
filterConditions = filterConditions.filter(
|
||||
c => c.customName !== conditionOrSavedFilter.customName,
|
||||
);
|
||||
}
|
||||
if (cond.conditions) {
|
||||
this.setState({ filterId: { ...cond, status: 'saved' } });
|
||||
this.setState({ conditionsOp: cond.conditionsOp });
|
||||
this.applyFilters([...cond.conditions]);
|
||||
if (conditionOrSavedFilter.conditions) {
|
||||
// A saved filter was passed in.
|
||||
const savedFilter = conditionOrSavedFilter;
|
||||
this.setState({
|
||||
filterId: { ...savedFilter, status: 'saved' },
|
||||
});
|
||||
this.setState({ conditionsOp: savedFilter.conditionsOp });
|
||||
this.applyFilters([...savedFilter.conditions]);
|
||||
} else {
|
||||
// A condition was passed in.
|
||||
const condition = conditionOrSavedFilter;
|
||||
this.setState({
|
||||
filterId: {
|
||||
...this.state.filterId,
|
||||
status: this.state.filterId && 'changed',
|
||||
},
|
||||
});
|
||||
this.applyFilters([...filters, cond]);
|
||||
this.applyFilters([...filterConditions, condition]);
|
||||
}
|
||||
if (this.state.search !== '') {
|
||||
this.onSearch(this.state.search);
|
||||
@@ -1294,18 +1306,21 @@ class AccountInternal extends PureComponent {
|
||||
|
||||
applyFilters = async conditions => {
|
||||
if (conditions.length > 0) {
|
||||
const customFilters = conditions
|
||||
const customQueryFilters = conditions
|
||||
.filter(cond => !!cond.customName)
|
||||
.map(f => f.filter);
|
||||
const { filters } = await send('make-filters-from-conditions', {
|
||||
conditions: conditions.filter(cond => !cond.customName),
|
||||
});
|
||||
.map(f => f.queryFilter);
|
||||
const { filters: queryFilters } = await send(
|
||||
'make-filters-from-conditions',
|
||||
{
|
||||
conditions: conditions.filter(cond => !cond.customName),
|
||||
},
|
||||
);
|
||||
const conditionsOpKey = this.state.conditionsOp === 'or' ? '$or' : '$and';
|
||||
this.currentQuery = this.rootQuery.filter({
|
||||
[conditionsOpKey]: [...filters, ...customFilters],
|
||||
[conditionsOpKey]: [...queryFilters, ...customQueryFilters],
|
||||
});
|
||||
|
||||
this.setState({ filters: conditions }, () => {
|
||||
this.setState({ filterConditions: conditions }, () => {
|
||||
this.updateQuery(this.currentQuery, true);
|
||||
});
|
||||
} else {
|
||||
@@ -1313,7 +1328,7 @@ class AccountInternal extends PureComponent {
|
||||
{
|
||||
transactions: [],
|
||||
transactionCount: 0,
|
||||
filters: conditions,
|
||||
filterConditions: conditions,
|
||||
},
|
||||
() => {
|
||||
this.fetchTransactions();
|
||||
@@ -1327,8 +1342,8 @@ class AccountInternal extends PureComponent {
|
||||
};
|
||||
|
||||
applySort = (field, ascDesc, prevField, prevAscDesc) => {
|
||||
const filters = this.state.filters;
|
||||
const isFiltered = filters.length > 0;
|
||||
const filterConditions = this.state.filterConditions;
|
||||
const isFiltered = filterConditions.length > 0;
|
||||
const sortField = getField(!field ? this.state.sort.field : field);
|
||||
const sortAscDesc = !ascDesc ? this.state.sort.ascDesc : ascDesc;
|
||||
const sortPrevField = getField(
|
||||
@@ -1395,7 +1410,7 @@ class AccountInternal extends PureComponent {
|
||||
// called directly from UI by sorting a column.
|
||||
// active filters need to be applied before sorting
|
||||
case isFiltered:
|
||||
this.applyFilters([...filters]);
|
||||
this.applyFilters([...filterConditions]);
|
||||
sortCurrentQuery(this, sortField, sortAscDesc);
|
||||
break;
|
||||
|
||||
@@ -1523,7 +1538,7 @@ class AccountInternal extends PureComponent {
|
||||
workingHard={workingHard}
|
||||
account={account}
|
||||
filterId={filterId}
|
||||
filtersList={this.props.filtersList}
|
||||
savedFilters={this.props.savedFilters}
|
||||
location={this.props.location}
|
||||
accountName={accountName}
|
||||
accountsSyncing={accountsSyncing}
|
||||
@@ -1540,7 +1555,7 @@ class AccountInternal extends PureComponent {
|
||||
isSorted={this.state.sort.length !== 0}
|
||||
reconcileAmount={reconcileAmount}
|
||||
search={this.state.search}
|
||||
filters={this.state.filters}
|
||||
filterConditions={this.state.filterConditions}
|
||||
conditionsOp={this.state.conditionsOp}
|
||||
savePrefs={this.props.savePrefs}
|
||||
pushModal={this.props.pushModal}
|
||||
@@ -1600,7 +1615,8 @@ class AccountInternal extends PureComponent {
|
||||
isNew={this.isNew}
|
||||
isMatched={this.isMatched}
|
||||
isFiltered={
|
||||
this.state.search !== '' || this.state.filters.length > 0
|
||||
this.state.search !== '' ||
|
||||
this.state.filterConditions.length > 0
|
||||
}
|
||||
dateFormat={dateFormat}
|
||||
hideFraction={hideFraction}
|
||||
@@ -1636,6 +1652,7 @@ class AccountInternal extends PureComponent {
|
||||
this.setState({ isAdding: false })
|
||||
}
|
||||
onCreatePayee={this.onCreatePayee}
|
||||
onApplyFilters={conditions => this.applyFilters(conditions)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -1683,36 +1700,10 @@ export function Account() {
|
||||
const modalShowing = useSelector(state => state.modals.modalStack.length > 0);
|
||||
const accountsSyncing = useSelector(state => state.account.accountsSyncing);
|
||||
const lastUndoState = useSelector(state => state.app.lastUndoState);
|
||||
const conditions =
|
||||
location.state && location.state.conditions
|
||||
? location.state.conditions
|
||||
: [];
|
||||
const filterConditions = location?.state?.filterConditions || [];
|
||||
|
||||
const state = {
|
||||
newTransactions,
|
||||
matchedTransactions,
|
||||
accounts,
|
||||
failedAccounts,
|
||||
dateFormat,
|
||||
hideFraction,
|
||||
expandSplits,
|
||||
showBalances,
|
||||
showCleared: !hideCleared,
|
||||
showReconciled: !hideReconciled,
|
||||
showExtraBalances,
|
||||
payees,
|
||||
modalShowing,
|
||||
accountsSyncing,
|
||||
lastUndoState,
|
||||
conditions,
|
||||
};
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const filtersList = useFilters();
|
||||
const actionCreators = useMemo(
|
||||
() => bindActionCreators(actions, dispatch),
|
||||
[dispatch],
|
||||
);
|
||||
const savedFiters = useFilters();
|
||||
const actionCreators = useActions();
|
||||
|
||||
const transform = useMemo(() => {
|
||||
const filterByAccount = queries.getAccountFilter(params.id, '_account');
|
||||
@@ -1741,17 +1732,31 @@ export function Account() {
|
||||
return (
|
||||
<SchedulesProvider transform={transform}>
|
||||
<SplitsExpandedProvider
|
||||
initialMode={state.expandSplits ? 'collapse' : 'expand'}
|
||||
initialMode={expandSplits ? 'collapse' : 'expand'}
|
||||
>
|
||||
<AccountHack
|
||||
{...state}
|
||||
newTransactions={newTransactions}
|
||||
matchedTransactions={matchedTransactions}
|
||||
accounts={accounts}
|
||||
failedAccounts={failedAccounts}
|
||||
dateFormat={dateFormat}
|
||||
hideFraction={hideFraction}
|
||||
expandSplits={expandSplits}
|
||||
showBalances={showBalances}
|
||||
showCleared={!hideCleared}
|
||||
showReconciled={!hideReconciled}
|
||||
showExtraBalances={showExtraBalances}
|
||||
payees={payees}
|
||||
modalShowing={modalShowing}
|
||||
accountsSyncing={accountsSyncing}
|
||||
lastUndoState={lastUndoState}
|
||||
filterConditions={filterConditions}
|
||||
categoryGroups={categoryGroups}
|
||||
{...actionCreators}
|
||||
modalShowing={state.modalShowing}
|
||||
accountId={params.id}
|
||||
categoryId={location?.state?.categoryId}
|
||||
location={location}
|
||||
filtersList={filtersList}
|
||||
savedFilters={savedFiters}
|
||||
/>
|
||||
</SplitsExpandedProvider>
|
||||
</SchedulesProvider>
|
||||
|
||||
@@ -141,7 +141,7 @@ export function Balances({
|
||||
showExtraBalances,
|
||||
onToggleExtraBalances,
|
||||
account,
|
||||
filteredItems,
|
||||
showFilteredBalances,
|
||||
transactions,
|
||||
}) {
|
||||
const selectedItems = useSelectedItems();
|
||||
@@ -200,9 +200,7 @@ export function Balances({
|
||||
{selectedItems.size > 0 && (
|
||||
<SelectedBalance selectedItems={selectedItems} account={account} />
|
||||
)}
|
||||
{filteredItems.length > 0 && (
|
||||
<FilteredBalance selectedItems={transactions} />
|
||||
)}
|
||||
{showFilteredBalances && <FilteredBalance selectedItems={transactions} />}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export function AccountHeader({
|
||||
accountName,
|
||||
account,
|
||||
filterId,
|
||||
filtersList,
|
||||
savedFilters,
|
||||
accountsSyncing,
|
||||
failedAccounts,
|
||||
accounts,
|
||||
@@ -54,7 +54,7 @@ export function AccountHeader({
|
||||
canCalculateBalance,
|
||||
isSorted,
|
||||
search,
|
||||
filters,
|
||||
filterConditions,
|
||||
conditionsOp,
|
||||
pushModal,
|
||||
onSearch,
|
||||
@@ -241,7 +241,7 @@ export function AccountHeader({
|
||||
showExtraBalances={showExtraBalances}
|
||||
onToggleExtraBalances={onToggleExtraBalances}
|
||||
account={account}
|
||||
filteredItems={filters}
|
||||
showFilteredBalances={filterConditions.length > 0}
|
||||
transactions={transactions}
|
||||
/>
|
||||
|
||||
@@ -320,7 +320,7 @@ export function AccountHeader({
|
||||
)}
|
||||
<Button
|
||||
type="bare"
|
||||
disabled={search !== '' || filters.length > 0}
|
||||
disabled={search !== '' || filterConditions.length > 0}
|
||||
style={{ padding: 6, marginLeft: 10 }}
|
||||
onClick={onToggleSplits}
|
||||
title={
|
||||
@@ -375,16 +375,16 @@ export function AccountHeader({
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
{filters && filters.length > 0 && (
|
||||
{filterConditions?.length > 0 && (
|
||||
<FiltersStack
|
||||
filters={filters}
|
||||
conditions={filterConditions}
|
||||
conditionsOp={conditionsOp}
|
||||
onUpdateFilter={onUpdateFilter}
|
||||
onDeleteFilter={onDeleteFilter}
|
||||
onClearFilters={onClearFilters}
|
||||
onReloadSavedFilter={onReloadSavedFilter}
|
||||
filterId={filterId}
|
||||
filtersList={filtersList}
|
||||
savedFilters={savedFilters}
|
||||
onCondOpChange={onCondOpChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -277,7 +277,7 @@ function BudgetInner(props: BudgetInnerProps) {
|
||||
};
|
||||
|
||||
const onShowActivity = (categoryId, month) => {
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
{ field: 'category', op: 'is', value: categoryId, type: 'id' },
|
||||
{
|
||||
field: 'date',
|
||||
@@ -290,7 +290,7 @@ function BudgetInner(props: BudgetInnerProps) {
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
filterConditions,
|
||||
categoryId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import { CondOpMenu } from './CondOpMenu';
|
||||
import { FilterExpression } from './FilterExpression';
|
||||
|
||||
type AppliedFiltersProps = {
|
||||
filters: RuleConditionEntity[];
|
||||
conditions: RuleConditionEntity[];
|
||||
onUpdate: (
|
||||
filter: RuleConditionEntity,
|
||||
newFilter: RuleConditionEntity,
|
||||
@@ -19,7 +19,7 @@ type AppliedFiltersProps = {
|
||||
};
|
||||
|
||||
export function AppliedFilters({
|
||||
filters,
|
||||
conditions,
|
||||
onUpdate,
|
||||
onDelete,
|
||||
conditionsOp,
|
||||
@@ -36,9 +36,9 @@ export function AppliedFilters({
|
||||
<CondOpMenu
|
||||
conditionsOp={conditionsOp}
|
||||
onCondOpChange={onCondOpChange}
|
||||
filters={filters}
|
||||
filters={conditions}
|
||||
/>
|
||||
{filters.map((filter: RuleConditionEntity, i: number) => (
|
||||
{conditions.map((filter: RuleConditionEntity, i: number) => (
|
||||
<FilterExpression
|
||||
key={i}
|
||||
customName={filter.customName}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { type TransactionFilterEntity } from 'loot-core/types/models';
|
||||
import { type RuleConditionEntity } from 'loot-core/types/models/rule';
|
||||
|
||||
import { Stack } from '../common/Stack';
|
||||
@@ -12,17 +13,17 @@ import {
|
||||
} from './SavedFilterMenuButton';
|
||||
|
||||
export function FiltersStack({
|
||||
filters,
|
||||
conditions,
|
||||
conditionsOp,
|
||||
onUpdateFilter,
|
||||
onDeleteFilter,
|
||||
onClearFilters,
|
||||
onReloadSavedFilter,
|
||||
filterId,
|
||||
filtersList,
|
||||
savedFilters,
|
||||
onCondOpChange,
|
||||
}: {
|
||||
filters: RuleConditionEntity[];
|
||||
conditions: RuleConditionEntity[];
|
||||
conditionsOp: string;
|
||||
onUpdateFilter: (
|
||||
filter: RuleConditionEntity,
|
||||
@@ -32,7 +33,7 @@ export function FiltersStack({
|
||||
onClearFilters: () => void;
|
||||
onReloadSavedFilter: (savedFilter: SavedFilter, value?: string) => void;
|
||||
filterId: SavedFilter;
|
||||
filtersList: RuleConditionEntity[];
|
||||
savedFilters: TransactionFilterEntity[];
|
||||
onCondOpChange: () => void;
|
||||
}) {
|
||||
return (
|
||||
@@ -44,7 +45,7 @@ export function FiltersStack({
|
||||
align="flex-start"
|
||||
>
|
||||
<AppliedFilters
|
||||
filters={filters}
|
||||
conditions={conditions}
|
||||
conditionsOp={conditionsOp}
|
||||
onCondOpChange={onCondOpChange}
|
||||
onUpdate={onUpdateFilter}
|
||||
@@ -52,12 +53,12 @@ export function FiltersStack({
|
||||
/>
|
||||
<View style={{ flex: 1 }} />
|
||||
<SavedFilterMenuButton
|
||||
filters={filters}
|
||||
conditions={conditions}
|
||||
conditionsOp={conditionsOp}
|
||||
filterId={filterId}
|
||||
onClearFilters={onClearFilters}
|
||||
onReloadSavedFilter={onReloadSavedFilter}
|
||||
filtersList={filtersList}
|
||||
savedFilters={savedFilters}
|
||||
/>
|
||||
</Stack>
|
||||
</View>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { send, sendCatch } from 'loot-core/src/platform/client/fetch';
|
||||
import { type TransactionFilterEntity } from 'loot-core/types/models';
|
||||
import { type RuleConditionEntity } from 'loot-core/types/models/rule';
|
||||
|
||||
import { SvgExpandArrow } from '../../icons/v0';
|
||||
@@ -20,19 +21,19 @@ export type SavedFilter = {
|
||||
};
|
||||
|
||||
export function SavedFilterMenuButton({
|
||||
filters,
|
||||
conditions,
|
||||
conditionsOp,
|
||||
filterId,
|
||||
onClearFilters,
|
||||
onReloadSavedFilter,
|
||||
filtersList,
|
||||
savedFilters,
|
||||
}: {
|
||||
filters: RuleConditionEntity[];
|
||||
conditions: RuleConditionEntity[];
|
||||
conditionsOp: string;
|
||||
filterId: SavedFilter;
|
||||
onClearFilters: () => void;
|
||||
onReloadSavedFilter: (savedFilter: SavedFilter, value?: string) => void;
|
||||
filtersList: RuleConditionEntity[];
|
||||
savedFilters: TransactionFilterEntity[];
|
||||
}) {
|
||||
const [nameOpen, setNameOpen] = useState(false);
|
||||
const [adding, setAdding] = useState(false);
|
||||
@@ -62,7 +63,7 @@ export function SavedFilterMenuButton({
|
||||
setAdding(false);
|
||||
setMenuOpen(false);
|
||||
savedFilter = {
|
||||
conditions: filters,
|
||||
conditions,
|
||||
conditionsOp,
|
||||
id: filterId.id,
|
||||
name: filterId.name,
|
||||
@@ -70,7 +71,7 @@ export function SavedFilterMenuButton({
|
||||
};
|
||||
const response = await sendCatch('filter-update', {
|
||||
state: savedFilter,
|
||||
filters: [...filtersList],
|
||||
filters: [...savedFilters],
|
||||
});
|
||||
|
||||
if (response.error) {
|
||||
@@ -106,7 +107,7 @@ export function SavedFilterMenuButton({
|
||||
async function onAddUpdate() {
|
||||
if (adding) {
|
||||
const newSavedFilter = {
|
||||
conditions: filters,
|
||||
conditions,
|
||||
conditionsOp,
|
||||
name,
|
||||
status: 'saved',
|
||||
@@ -114,7 +115,7 @@ export function SavedFilterMenuButton({
|
||||
|
||||
const response = await sendCatch('filter-create', {
|
||||
state: newSavedFilter,
|
||||
filters: [...filtersList],
|
||||
filters: [...savedFilters],
|
||||
});
|
||||
|
||||
if (response.error) {
|
||||
@@ -140,7 +141,7 @@ export function SavedFilterMenuButton({
|
||||
|
||||
const response = await sendCatch('filter-update', {
|
||||
state: updatedFilter,
|
||||
filters: [...filtersList],
|
||||
filters: [...savedFilters],
|
||||
});
|
||||
|
||||
if (response.error) {
|
||||
@@ -155,7 +156,7 @@ export function SavedFilterMenuButton({
|
||||
|
||||
return (
|
||||
<View>
|
||||
{filters.length > 0 && (
|
||||
{conditions.length > 0 && (
|
||||
<Button
|
||||
type="bare"
|
||||
style={{ marginTop: 10 }}
|
||||
|
||||
@@ -164,7 +164,7 @@ export function Header({
|
||||
align="flex-start"
|
||||
>
|
||||
<AppliedFilters
|
||||
filters={filters}
|
||||
conditions={filters}
|
||||
onUpdate={onUpdateFilter}
|
||||
onDelete={onDeleteFilter}
|
||||
conditionsOp={conditionsOp}
|
||||
|
||||
@@ -191,7 +191,7 @@ export function BarGraph({
|
||||
.map(e => e.id);
|
||||
const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id);
|
||||
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
...filters,
|
||||
{ field, op: 'is', value: item.id, type: 'id' },
|
||||
{
|
||||
@@ -232,7 +232,7 @@ export function BarGraph({
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
filterConditions,
|
||||
categoryId: item.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -215,7 +215,7 @@ export function DonutGraph({
|
||||
.map(e => e.id);
|
||||
const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id);
|
||||
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
...filters,
|
||||
{ field, op: 'is', value: item.id, type: 'id' },
|
||||
{
|
||||
@@ -256,7 +256,7 @@ export function DonutGraph({
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
filterConditions,
|
||||
categoryId: item.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -150,7 +150,7 @@ export function LineGraph({
|
||||
.map(e => e.id);
|
||||
const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id);
|
||||
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
...filters,
|
||||
{ field, op: 'is', value: id, type: 'id' },
|
||||
{
|
||||
@@ -183,7 +183,7 @@ export function LineGraph({
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
filterConditions,
|
||||
categoryId: item.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -181,7 +181,7 @@ export function StackedBarGraph({
|
||||
.map(e => e.id);
|
||||
const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id);
|
||||
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
...filters,
|
||||
{ field, op: 'is', value: id, type: 'id' },
|
||||
{
|
||||
@@ -214,7 +214,7 @@ export function StackedBarGraph({
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
filterConditions,
|
||||
categoryId: item.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -539,7 +539,7 @@ export function CustomReport() {
|
||||
align="flex-start"
|
||||
>
|
||||
<AppliedFilters
|
||||
filters={filters}
|
||||
conditions={filters}
|
||||
onUpdate={(oldFilter, newFilter) => {
|
||||
setSessionReport(
|
||||
'conditions',
|
||||
|
||||
@@ -86,6 +86,7 @@ export function TransactionList({
|
||||
onRefetch,
|
||||
onCloseAddTransaction,
|
||||
onCreatePayee,
|
||||
onApplyFilters,
|
||||
}) {
|
||||
const transactionsLatest = useRef();
|
||||
const navigate = useNavigate();
|
||||
@@ -167,15 +168,10 @@ export function TransactionList({
|
||||
});
|
||||
|
||||
const onNavigateToFilteredTagView = useCallback(noteTag => {
|
||||
const conditions = [
|
||||
const filterConditions = [
|
||||
{ field: 'notes', op: 'contains', value: noteTag, type: 'string' },
|
||||
];
|
||||
navigate('/accounts', {
|
||||
state: {
|
||||
goBack: true,
|
||||
conditions,
|
||||
},
|
||||
});
|
||||
onApplyFilters(filterConditions);
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user