Skip to content

Commit

Permalink
6.8.0-pre (#42)
Browse files Browse the repository at this point in the history
* add the ability to categorise by description, MVP tho

* 6.8.0-pre
  • Loading branch information
errietta authored Feb 10, 2020
1 parent 402e409 commit 8d69ea0
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperbudget-frontend",
"version": "6.7.0",
"version": "6.8.0-pre",
"description": "",
"main": "src/index.tsx",
"scripts": {
Expand Down
64 changes: 59 additions & 5 deletions src/components/Category/CategoriseTransactionComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@ import {
Category, FormattedTransaction
} from '@hyperbudget/hyperbudget-core';

import { CategorisationType } from '../../lib/Util/Util';

interface CategoriseTransactionState {
categoriesForceAdd: Set<string>,
categoriesForceRemove: Set<string>,
categoriesForceAdd: Set<string>;
categoriesForceRemove: Set<string>;
categorisationType: CategorisationType;
txnDescriptionMatch: string;
};

interface CategoriseTransactionProps {
categories: Category[];
transaction: FormattedTransaction;
onDoneCategorise: () => void;
onSaveCustomCategories: (forceAdd: Set<string>, forceRm: Set<string>) => void;
onSaveCustomCategories: (
forceAdd: Set<string>, forceRm: Set<string>,
categorisationType: CategorisationType,
txnDescriptionMatch: string,
) => void;
};

export class CategoriseTransactionComponent extends React.Component
Expand Down Expand Up @@ -53,10 +61,12 @@ export class CategoriseTransactionComponent extends React.Component
this.state = {
categoriesForceAdd: new Set(),
categoriesForceRemove: new Set(),
categorisationType: CategorisationType.IDENTIFIER,
txnDescriptionMatch: this.props.transaction.description,
};
}

inputChanged(evt): void {
selectedCategoriesChanged(evt): void {
const checkbox = evt.target;
const catId = checkbox.value;
console.log(checkbox.checked);
Expand All @@ -79,6 +89,24 @@ export class CategoriseTransactionComponent extends React.Component
}
}

selectedTypeChanged(evt): void {
const radio = evt.target;
const selectedType: CategorisationType = Number(radio.value);

this.setState({
categorisationType: selectedType,
})
}

txnDescriptionChanged(evt): void {
const text = evt.target;
const description = text.value;

this.setState({
txnDescriptionMatch: description,
})
}

render () {
return (
<div className='categorise_transaction'>
Expand All @@ -95,21 +123,47 @@ export class CategoriseTransactionComponent extends React.Component
this.shownCategories.map((category, idx) => (
<label className='categorise_transaction--label' key={category.name+"-"+idx}>
<input
onChange={this.inputChanged.bind(this)}
onChange={this.selectedCategoriesChanged.bind(this)}
defaultChecked={this.txnIncludesCat(category)}
disabled={this.txnIncludesCat(category) && !this.txnHasCustomCategory(category)}
value={category.id}
type="checkbox" /> { category.name }
</label>
))
)}
<h3>Categorise by</h3>
<label className="categorise_transaction--label">
<input
onChange={this.selectedTypeChanged.bind(this)}
value={CategorisationType.IDENTIFIER}
checked={this.state.categorisationType === CategorisationType.IDENTIFIER}
type="radio" /> This transaction only (transaction identifier)
</label>
<label className="categorise_transaction--label">
<input
onChange={this.selectedTypeChanged.bind(this)}
value={CategorisationType.DESCRIPTION}
checked={this.state.categorisationType === CategorisationType.DESCRIPTION}
type="radio" />
All transactions matching the following description:
<input
type="text"
value={this.state.txnDescriptionMatch}
onChange={this.txnDescriptionChanged.bind(this)}
disabled={this.state.categorisationType !== CategorisationType.DESCRIPTION}
/>
</label>

<hr/>
<button
className='btn-primary btn'
role='button' value="Save"
onClick={
() => this.props.onSaveCustomCategories(
this.state.categoriesForceAdd,
this.state.categoriesForceRemove,
this.state.categorisationType,
this.state.txnDescriptionMatch
)
}
>
Expand Down
49 changes: 35 additions & 14 deletions src/components/Report/ReportComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import 'bootstrap/dist/css/bootstrap.min.css';

import {
Report, ReportFactory,
Category, Categoriser,
reportManager, FormattedTransaction, Transaction
Category, Categoriser, RuleMatchMode,
reportManager, FormattedTransaction, Transaction,
} from '@hyperbudget/hyperbudget-core';

import { StatementUploaderComponent } from '../StatementUploader/StatementUploaderComponent';
Expand All @@ -31,7 +31,11 @@ import { set_transactions, set_categories } from '../../lib/User/User';

import { State } from '../../lib/State/State';

import { deResponsifyPage, responsifyPage, disableScroll, enableScroll } from '../../lib/Util/Util';
import {
deResponsifyPage, responsifyPage,
disableScroll, enableScroll,
CategorisationType,
} from '../../lib/Util/Util';
import { LoadingSpinner } from '../LoadingSpinner';

import queryString from 'query-string';
Expand Down Expand Up @@ -285,7 +289,8 @@ class ReportComponent extends React.Component<ReportComponentProps, ReportCompon


private onSaveCustomCategories (
categoriesForceAdd: Set<string>, categoriesForceRemove: Set<string>
categoriesForceAdd: Set<string>, categoriesForceRemove: Set<string>,
categorisationType: CategorisationType, txnDescriptionMatch: string
): void {
console.log(categoriesForceAdd, categoriesForceRemove);

Expand All @@ -304,20 +309,36 @@ class ReportComponent extends React.Component<ReportComponentProps, ReportCompon
// accidentally, this time it's 100% on purpose. I love js.
currentCat = this.removeCustomCategory(currentCat, txn);

if (
currentCat.category_rules.identifier &&
currentCat.category_rules.identifier.rules
) {
currentCat.category_rules.identifier.rules.push(['=', txn.identifier]);
} else {
currentCat.category_rules.identifier = {
"rules": [['=', txn.identifier]]
};
if (categorisationType === CategorisationType.IDENTIFIER) {
if (
currentCat.category_rules.identifier &&
currentCat.category_rules.identifier.rules
) {
currentCat.category_rules.identifier.rules.push(['=', txn.identifier]);
} else {
currentCat.category_rules.identifier = {
"rules": [['=', txn.identifier]]
};
}
} else if (categorisationType === CategorisationType.DESCRIPTION) {
if (
currentCat.category_rules.description &&
currentCat.category_rules.description.rules
) {
currentCat.category_rules.description.mode = RuleMatchMode.Flex;
currentCat.category_rules.description.rules.push(['=~', txnDescriptionMatch]);
} else {
currentCat.category_rules.description = {
"mode": RuleMatchMode.Flex,
"rules": [['=~', txnDescriptionMatch]],
};
}
}
});

// we only support removing ones that were
// added manually through this same code at the moment
// added manually through this same code
// and are identifier matches
categoriesForceRemove.forEach(id => {
let currentCat = categoriesHash[id];
currentCat = this.removeCustomCategory(currentCat, txn);
Expand Down
5 changes: 5 additions & 0 deletions src/lib/Util/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,8 @@ export const enableScroll = (): void => {
appContainer.style.overflow = "auto";
}
}

export enum CategorisationType {
IDENTIFIER,
DESCRIPTION,
};

0 comments on commit 8d69ea0

Please sign in to comment.