monopyly 1.6.0__py3-none-any.whl → 1.6.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- monopyly/CHANGELOG.md +15 -0
- monopyly/_version.py +22 -4
- monopyly/banking/forms.py +4 -0
- monopyly/common/forms/_forms.py +5 -14
- monopyly/common/forms/fields.py +0 -9
- monopyly/common/forms/utils.py +3 -3
- monopyly/core/context_processors.py +3 -21
- monopyly/credit/cards.py +1 -1
- monopyly/credit/forms.py +6 -2
- monopyly/credit/transactions/activity/parser.py +1 -1
- monopyly/static/css/style.css +4 -0
- monopyly/static/js/bind-tag-actions.js +174 -86
- monopyly/static/js/highlight-discrepant-transactions.js +1 -0
- monopyly/templates/banking/account_form/account_form_page_new.html +10 -8
- monopyly/templates/banking/account_page.html +24 -24
- monopyly/templates/banking/accounts_page.html +8 -6
- monopyly/templates/common/tag_tree.html +4 -1
- monopyly/templates/common/tags_page.html +15 -13
- monopyly/templates/core/index.html +12 -8
- monopyly/templates/core/profile.html +18 -19
- monopyly/templates/credit/account_page.html +17 -17
- monopyly/templates/credit/card_form/card_form_page_new.html +8 -5
- monopyly/templates/credit/statement_page.html +43 -44
- monopyly/templates/credit/statement_reconciliation/statement_reconciliation_page.html +19 -19
- monopyly/templates/credit/statements_page.html +13 -13
- monopyly/templates/credit/transaction_form/transaction_form_page_update.html +9 -9
- monopyly/templates/credit/transactions_page.html +28 -28
- monopyly/templates/layout.html +7 -5
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/METADATA +6 -6
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/RECORD +34 -34
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/WHEEL +1 -1
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/entry_points.txt +0 -0
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/licenses/COPYING +0 -0
- {monopyly-1.6.0.dist-info → monopyly-1.6.2.dist-info}/licenses/LICENSE +0 -0
monopyly/CHANGELOG.md
CHANGED
|
@@ -237,4 +237,19 @@
|
|
|
237
237
|
- Update JavaScript libraries (jQuery, Chartist)
|
|
238
238
|
|
|
239
239
|
|
|
240
|
+
### 1.6.1
|
|
241
|
+
|
|
242
|
+
- Allow pie chart labels to overflow the SVG container
|
|
243
|
+
- Define JavaScript elements in header (deferring execution when logical)
|
|
244
|
+
- Bump dependencies
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
### 1.6.2
|
|
248
|
+
|
|
249
|
+
- Fix bug in the transaction tag tree template preventing new subtags in the same subtag subtree
|
|
250
|
+
- Refactor JavaScript used to manage the transaction tag tree
|
|
251
|
+
- Add specificity to the reconciliation tool when parsing payment columns (when otherwise unidentified, payment transactions are determined by the presence of the isolated word "payment" in the description field)
|
|
252
|
+
- Bump dependencies
|
|
253
|
+
|
|
254
|
+
|
|
240
255
|
<a name="bottom" id="bottom"></a>
|
monopyly/_version.py
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
3
13
|
TYPE_CHECKING = False
|
|
4
14
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
6
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
7
20
|
else:
|
|
8
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
9
23
|
|
|
10
24
|
version: str
|
|
11
25
|
__version__: str
|
|
12
26
|
__version_tuple__: VERSION_TUPLE
|
|
13
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '1.6.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 6, 2)
|
|
14
33
|
|
|
15
|
-
|
|
16
|
-
__version_tuple__ = version_tuple = (1, 6, 0)
|
|
34
|
+
__commit_id__ = commit_id = None
|
monopyly/banking/forms.py
CHANGED
|
@@ -115,6 +115,10 @@ class BankAccountForm(EntryForm):
|
|
|
115
115
|
}
|
|
116
116
|
return account_type_data
|
|
117
117
|
|
|
118
|
+
def gather_entry_data(self, entry):
|
|
119
|
+
"""Gather data for the form from the given database entry."""
|
|
120
|
+
raise NotImplementedError
|
|
121
|
+
|
|
118
122
|
# Fields to identify the bank/account type information for the account
|
|
119
123
|
bank_info = FormField(BankSubform)
|
|
120
124
|
account_type_info = FormField(AccountTypeSubform)
|
monopyly/common/forms/_forms.py
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
General form constructions.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from abc import
|
|
5
|
+
from abc import abstractmethod
|
|
6
6
|
from datetime import date
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from dry_foundation.forms import AbstractFlaskForm, FlaskSubform
|
|
9
9
|
from wtforms.fields import StringField, SubmitField
|
|
10
10
|
from wtforms.validators import DataRequired
|
|
11
11
|
|
|
@@ -15,12 +15,7 @@ from .fields import CurrencyField, DateField
|
|
|
15
15
|
form_err_msg = "There was an improper value in your form. Please try again."
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class
|
|
19
|
-
# Defined to allow the forms to also to be abstract base classes
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class EntryForm(FlaskForm, metaclass=AbstractEntryFormMixinMeta):
|
|
18
|
+
class EntryForm(AbstractFlaskForm):
|
|
24
19
|
"""
|
|
25
20
|
A form designed to accept database entry information.
|
|
26
21
|
|
|
@@ -85,11 +80,8 @@ class EntryForm(FlaskForm, metaclass=AbstractEntryFormMixinMeta):
|
|
|
85
80
|
)
|
|
86
81
|
|
|
87
82
|
|
|
88
|
-
class EntrySubform(EntryForm):
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
def __init__(self, *args, **kwargs):
|
|
92
|
-
super().__init__(meta={"csrf": False}, *args, **kwargs)
|
|
83
|
+
class EntrySubform(FlaskSubform, EntryForm):
|
|
84
|
+
"""A subform implementing ``EntryForm`` behavior."""
|
|
93
85
|
|
|
94
86
|
|
|
95
87
|
class AcquisitionSubform(EntrySubform):
|
|
@@ -149,7 +141,6 @@ class TransactionForm(EntryForm):
|
|
|
149
141
|
}
|
|
150
142
|
return data
|
|
151
143
|
|
|
152
|
-
@abstractmethod
|
|
153
144
|
def gather_entry_data(self, entry):
|
|
154
145
|
if self.subtransaction_model is None:
|
|
155
146
|
raise RuntimeError(
|
monopyly/common/forms/fields.py
CHANGED
|
@@ -24,15 +24,6 @@ class DateField(wtforms_fields.DateField):
|
|
|
24
24
|
super().__init__(*args, filters=filters, **kwargs)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class OptionalDateField(DateField):
|
|
28
|
-
"""A date field where the field value is optional."""
|
|
29
|
-
|
|
30
|
-
def process_formdata(self, valuelist):
|
|
31
|
-
"""Process data from the form, ignoring an ommitted value."""
|
|
32
|
-
if valuelist != [""]:
|
|
33
|
-
super().process_formdata(valuelist)
|
|
34
|
-
|
|
35
|
-
|
|
36
27
|
class CurrencyField(wtforms_fields.DecimalField):
|
|
37
28
|
"""A decimal field with currency-specific customizations."""
|
|
38
29
|
|
monopyly/common/forms/utils.py
CHANGED
|
@@ -113,9 +113,9 @@ def extend_field_list_for_ajax(form_class, field_list_name, field_list_count):
|
|
|
113
113
|
|
|
114
114
|
Parameters
|
|
115
115
|
----------
|
|
116
|
-
form_class :
|
|
117
|
-
The class (not class instance) containing the field list to
|
|
118
|
-
extended.
|
|
116
|
+
form_class : type
|
|
117
|
+
The form class (not class instance) containing the field list to
|
|
118
|
+
be extended.
|
|
119
119
|
field_list_name : str
|
|
120
120
|
The name of the field list to be extended.
|
|
121
121
|
field_list_count : int
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
Filters defined for the application.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from importlib import import_module
|
|
5
|
+
from dry_foundation.utils import define_basic_template_global_variables
|
|
7
6
|
|
|
8
7
|
from .actions import determine_summary_balance_svg_viewbox_width
|
|
9
8
|
from .blueprint import bp
|
|
@@ -11,13 +10,8 @@ from .blueprint import bp
|
|
|
11
10
|
|
|
12
11
|
@bp.app_context_processor
|
|
13
12
|
def inject_global_template_variables():
|
|
14
|
-
"""Inject template
|
|
15
|
-
|
|
16
|
-
"app_version": _display_version(),
|
|
17
|
-
"copyright_statement": f"© {date.today().year}",
|
|
18
|
-
"date_today": date.today(),
|
|
19
|
-
}
|
|
20
|
-
return template_globals
|
|
13
|
+
"""Inject template variables globally into the template context."""
|
|
14
|
+
return define_basic_template_global_variables("monopyly._version")
|
|
21
15
|
|
|
22
16
|
|
|
23
17
|
@bp.app_context_processor
|
|
@@ -27,15 +21,3 @@ def inject_utility_functions():
|
|
|
27
21
|
"calculate_summary_balance_width": determine_summary_balance_svg_viewbox_width,
|
|
28
22
|
}
|
|
29
23
|
return utility_functions
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def _display_version():
|
|
33
|
-
"""Show the version (without commit information)."""
|
|
34
|
-
try:
|
|
35
|
-
version = import_module("monopyly._version").version
|
|
36
|
-
except ModuleNotFoundError:
|
|
37
|
-
# Fallback action in case Hatch VCS fails
|
|
38
|
-
display_version = ""
|
|
39
|
-
else:
|
|
40
|
-
display_version = version.split("+")[0]
|
|
41
|
-
return display_version
|
monopyly/credit/cards.py
CHANGED
|
@@ -137,7 +137,7 @@ def save_card(form, card_id=None):
|
|
|
137
137
|
|
|
138
138
|
Parameters
|
|
139
139
|
----------
|
|
140
|
-
form :
|
|
140
|
+
form : CreditCardForm
|
|
141
141
|
The form beign used to provide the data being saved.
|
|
142
142
|
card_id : int
|
|
143
143
|
The ID of hte card to be saved. If provided, the named card will
|
monopyly/credit/forms.py
CHANGED
|
@@ -5,6 +5,7 @@ Generate credit card forms for the user to complete.
|
|
|
5
5
|
from flask import abort
|
|
6
6
|
from wtforms.fields import (
|
|
7
7
|
BooleanField,
|
|
8
|
+
DateField,
|
|
8
9
|
FieldList,
|
|
9
10
|
FormField,
|
|
10
11
|
IntegerField,
|
|
@@ -18,7 +19,6 @@ from ..common.forms import AcquisitionSubform, EntryForm, EntrySubform, Transact
|
|
|
18
19
|
from ..common.forms.fields import (
|
|
19
20
|
CustomChoiceSelectField,
|
|
20
21
|
LastFourDigitsField,
|
|
21
|
-
OptionalDateField,
|
|
22
22
|
StringField,
|
|
23
23
|
)
|
|
24
24
|
from ..common.forms.utils import Autocompleter
|
|
@@ -152,6 +152,10 @@ class CardStatementTransferForm(EntryForm):
|
|
|
152
152
|
transfer = RadioField("transfer", choices=[("yes", "Yes"), ("no", "No")])
|
|
153
153
|
submit = SubmitField("Continue")
|
|
154
154
|
|
|
155
|
+
def gather_entry_data(self, entry):
|
|
156
|
+
"""Gather data for the form from the given database entry."""
|
|
157
|
+
raise NotImplementedError
|
|
158
|
+
|
|
155
159
|
|
|
156
160
|
class CreditTransactionForm(TransactionForm):
|
|
157
161
|
"""Form to input/edit credit card transactions."""
|
|
@@ -193,7 +197,7 @@ class CreditTransactionForm(TransactionForm):
|
|
|
193
197
|
# Fields to identify the card/bank information for the statement
|
|
194
198
|
card_info = FormField(CardSubform)
|
|
195
199
|
# Fields pertaining to the statement
|
|
196
|
-
issue_date =
|
|
200
|
+
issue_date = DateField("Statement Date", [Optional()])
|
|
197
201
|
|
|
198
202
|
def get_statement(self, transaction_date):
|
|
199
203
|
"""Get the credit card statement described by the form data."""
|
|
@@ -213,7 +213,7 @@ class _TransactionActivityParser:
|
|
|
213
213
|
def _infer_payment_row(row):
|
|
214
214
|
# Infer whether the row constitutes a payment transaction
|
|
215
215
|
contextual_info = [row[i].lower() for i in contextual_column_indices]
|
|
216
|
-
return any("payment" in element for element in contextual_info)
|
|
216
|
+
return any("payment" in element.split() for element in contextual_info)
|
|
217
217
|
|
|
218
218
|
payment_rows = list(filter(_infer_payment_row, raw_data))
|
|
219
219
|
return self._extrapolate_payments_positive(payment_rows, raw_data)
|
monopyly/static/css/style.css
CHANGED
|
@@ -13,111 +13,199 @@ import { executeAjaxRequest } from './modules/ajax.js';
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
(function() {
|
|
16
|
-
|
|
17
|
-
const endpointAddTag = ADD_TAG_ENDPOINT;
|
|
18
|
-
const endpointRemoveTag = REMOVE_TAG_ENDPOINT;
|
|
19
|
-
// Set animation parameters
|
|
20
|
-
const slideTime = 300;
|
|
21
16
|
// Identify the buttons
|
|
22
|
-
const $
|
|
23
|
-
const $
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
17
|
+
const $createTagButtons = $('#transaction-tags .new-tag.button');
|
|
18
|
+
const $deleteTagButtons = $('#transaction-tags .action.button.delete');
|
|
19
|
+
bindTagButtonBehavior($createTagButtons, $deleteTagButtons);
|
|
20
|
+
|
|
21
|
+
})();
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create the tag manager.
|
|
26
|
+
*
|
|
27
|
+
* @param {JQuery} $createTagButtons - Buttons for adding subtags to one or
|
|
28
|
+
* more tags.
|
|
29
|
+
* @param {JQuery} $deleteTagButtons - Buttons for removing tags.
|
|
30
|
+
*/
|
|
31
|
+
function bindTagButtonBehavior($createTagButtons, $deleteTagButtons) {
|
|
32
|
+
console.log('bind create buttons', $createTagButtons);
|
|
33
|
+
console.log('bind delete buttons', $deleteTagButtons);
|
|
34
|
+
$createTagButtons.on('click', function() {
|
|
35
|
+
const $button = $(this);
|
|
36
|
+
const behavior = new TagCreation($button);
|
|
37
|
+
behavior.perform();
|
|
38
|
+
});
|
|
39
|
+
$deleteTagButtons.on('click', function() {
|
|
40
|
+
const $button = $(this);
|
|
41
|
+
const behavior = new TagDeletion($button);
|
|
42
|
+
behavior.perform();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A class for managing transaction tags and the behavior of their buttons.
|
|
49
|
+
*/
|
|
50
|
+
class TagButtonBehavior {
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create the tag manager.
|
|
54
|
+
*
|
|
55
|
+
* @param {JQuery} $button - A button belonging to a tag.
|
|
56
|
+
*/
|
|
57
|
+
constructor($button) {
|
|
58
|
+
this.$container = $button.closest('.tag-container');
|
|
59
|
+
this.$tag = this.$container.children('.tag-area').find('.tag');
|
|
60
|
+
this.$tags = this.$container.children('ul.tags');
|
|
61
|
+
this.$input = this.$tags.children('input.new-tag');
|
|
62
|
+
// Set animation parameters
|
|
63
|
+
this.slideTime = 300;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A class for managing transaction tags creation behavior.
|
|
70
|
+
*/
|
|
71
|
+
class TagCreation extends TagButtonBehavior {
|
|
72
|
+
|
|
73
|
+
#endpoint = ADD_TAG_ENDPOINT;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Create the tag creator.
|
|
77
|
+
*
|
|
78
|
+
* @param {JQuery} $button - A button belonging to a tag.
|
|
79
|
+
*/
|
|
80
|
+
constructor($button) {
|
|
81
|
+
super($button);
|
|
82
|
+
self = this;
|
|
83
|
+
this.$input.on('blur', function() {
|
|
84
|
+
self.#dropInputFocus();
|
|
50
85
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
removeTag($tag);
|
|
58
|
-
// Remove the tag from the display
|
|
59
|
-
const $tagContainer = $tag.closest('.tag-area');
|
|
60
|
-
$tagContainer.slideUp(300, function() {
|
|
61
|
-
$(this).remove()
|
|
62
|
-
});
|
|
86
|
+
this.$input.on('keydown', function() {
|
|
87
|
+
if (event.key == 'Escape') {
|
|
88
|
+
self.#clearInput();
|
|
89
|
+
this.blur();
|
|
90
|
+
} else if (event.key == 'Enter') {
|
|
91
|
+
this.blur();
|
|
63
92
|
}
|
|
64
93
|
});
|
|
65
94
|
}
|
|
66
95
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Perform the behavior.
|
|
98
|
+
*/
|
|
99
|
+
perform() {
|
|
100
|
+
this.#showInput();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Show the input box to collect new tag information.
|
|
105
|
+
*/
|
|
106
|
+
#showInput() {
|
|
107
|
+
console.log('showing input', this.$input);
|
|
108
|
+
self = this;
|
|
109
|
+
this.$input.slideDown(this.slideTime, function() {
|
|
110
|
+
self.$input.addClass('visible');
|
|
111
|
+
self.$input.focus();
|
|
112
|
+
console.log('focus', self.$input);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Perform a specific action when the input loses focus.
|
|
118
|
+
*/
|
|
119
|
+
#dropInputFocus() {
|
|
120
|
+
if (this.$input.val()) {
|
|
121
|
+
this.#createTag();
|
|
122
|
+
this.#hideFilledInput();
|
|
123
|
+
} else {
|
|
124
|
+
this.#hideEmptyInput();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Create the new tag in the database.
|
|
130
|
+
*/
|
|
131
|
+
#createTag() {
|
|
70
132
|
const rawData = {
|
|
71
|
-
'tag_name':
|
|
72
|
-
'parent':
|
|
133
|
+
'tag_name': this.$input.val(),
|
|
134
|
+
'parent': this.$tag.text()
|
|
73
135
|
};
|
|
74
|
-
// Execute the AJAX request and
|
|
75
|
-
|
|
76
|
-
// Add the AJAX request response to the DOM before the input
|
|
77
|
-
$input.before(response);
|
|
78
|
-
hideFilledInput($input);
|
|
79
|
-
// Bind the buttons for the newly added tag
|
|
80
|
-
const $buttonAddTag = $input.prev().find('.new-tag.button');
|
|
81
|
-
const $buttonRemoveTag = $input.prev().find('.action.button.delete');
|
|
82
|
-
bindTagCreator($buttonAddTag, $buttonRemoveTag);
|
|
83
|
-
}
|
|
84
|
-
executeAjaxRequest(endpointAddTag, rawData, addTag);
|
|
136
|
+
// Execute the AJAX request and place the new tag
|
|
137
|
+
executeAjaxRequest(this.#endpoint, rawData, this.#placeNewTag.bind(this));
|
|
85
138
|
}
|
|
86
139
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Add the new tag to the DOM before the input.
|
|
142
|
+
*/
|
|
143
|
+
#placeNewTag(newTagHTML) {
|
|
144
|
+
const $newTag = $(newTagHTML);
|
|
145
|
+
this.$input.before($newTag);
|
|
146
|
+
// Bind behavior functionality to the newly created/placed tag buttons
|
|
147
|
+
bindTagButtonBehavior(
|
|
148
|
+
$newTag.find('.new-tag.button'), $newTag.find('.action.button.delete')
|
|
149
|
+
);
|
|
92
150
|
}
|
|
93
151
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Hide the input immediately.
|
|
154
|
+
*/
|
|
155
|
+
#hideFilledInput() {
|
|
156
|
+
this.$input.hide();
|
|
157
|
+
this.$input.removeClass('visible');
|
|
158
|
+
this.#clearInput();
|
|
98
159
|
}
|
|
99
160
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Hide the (empty) input gracefully.
|
|
163
|
+
*/
|
|
164
|
+
#hideEmptyInput() {
|
|
165
|
+
this.$input.removeClass('visible');
|
|
166
|
+
this.$input.slideUp(this.slideTime);
|
|
167
|
+
console.log('hiding empty input', this.$input);
|
|
104
168
|
}
|
|
105
169
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Clear the input.
|
|
172
|
+
*/
|
|
173
|
+
#clearInput() {
|
|
174
|
+
this.$input.val('');
|
|
109
175
|
}
|
|
110
176
|
|
|
111
|
-
|
|
112
|
-
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* A class for managing transaction tags deletion behavior.
|
|
182
|
+
*/
|
|
183
|
+
class TagDeletion extends TagButtonBehavior {
|
|
184
|
+
|
|
185
|
+
#endpoint = REMOVE_TAG_ENDPOINT;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Perform the behavior.
|
|
189
|
+
*/
|
|
190
|
+
perform() {
|
|
191
|
+
if (this.#confirmDelete()) {
|
|
192
|
+
this.#removeTag();
|
|
193
|
+
}
|
|
113
194
|
}
|
|
114
195
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
196
|
+
/**
|
|
197
|
+
* Remove the tag from the database.
|
|
198
|
+
*/
|
|
199
|
+
#removeTag() {
|
|
200
|
+
const rawData = {'tag_name': this.$tag.html()};
|
|
201
|
+
// Execute the AJAX request to delete the tag
|
|
202
|
+
executeAjaxRequest(this.#endpoint, rawData);
|
|
203
|
+
// Remove the tag from the display
|
|
204
|
+
this.$container.slideUp(this.slideTime, function() {this.remove()});
|
|
121
205
|
}
|
|
122
206
|
|
|
123
|
-
|
|
207
|
+
#confirmDelete() {
|
|
208
|
+
return confirm('Are you sure you want to delete this tag?');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
{% extends "common/form_page.html" %}
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
{% block javascript %}
|
|
5
|
+
|
|
6
|
+
<script type="module" src="{{ url_for('static', filename='js/display-new-bank-inputs.js') }}">
|
|
7
|
+
</script>
|
|
8
|
+
<script type="module" src="{{ url_for('static', filename='js/display-new-account-type-inputs.js') }}">
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
|
|
4
14
|
{% block title %}
|
|
5
15
|
New Bank Account
|
|
6
16
|
{% endblock %}
|
|
@@ -13,11 +23,3 @@
|
|
|
13
23
|
{% endwith %}
|
|
14
24
|
|
|
15
25
|
{% endblock %}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{% block javascript %}
|
|
19
|
-
<script type="module" src="{{ url_for('static', filename='js/display-new-bank-inputs.js') }}">
|
|
20
|
-
</script>
|
|
21
|
-
<script type="module" src="{{ url_for('static', filename='js/display-new-account-type-inputs.js') }}">
|
|
22
|
-
</script>
|
|
23
|
-
{% endblock %}
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
{% extends 'layout.html' %}
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
{% block javascript %}
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
const EXPAND_TRANSACTION_ENDPOINT = "{{ url_for('banking.expand_transaction') }}";
|
|
8
|
+
const LINKED_TRANSACTION_ENDPOINT = "{{ url_for('banking.show_linked_transaction') }}";
|
|
9
|
+
const LOAD_TRANSACTIONS_ENDPOINT = "{{ url_for('banking.load_more_transactions') }}";
|
|
10
|
+
const LOAD_TRANSACTIONS_SELECTORS = {
|
|
11
|
+
"account_id": {{ account.id }},
|
|
12
|
+
"block_count": 1
|
|
13
|
+
};
|
|
14
|
+
const BALANCE_CHART_DATA = {{ chart_data|tojson }};
|
|
15
|
+
</script>
|
|
16
|
+
<script type="module" src="{{ url_for('static', filename='js/load-more-transactions.js') }}">
|
|
17
|
+
</script>
|
|
18
|
+
<script type="module" src="{{ url_for('static', filename='js/expand-transaction.js') }}">
|
|
19
|
+
</script>
|
|
20
|
+
<script type="module" src="{{ url_for('static', filename='js/show-linked-transaction.js') }}">
|
|
21
|
+
</script>
|
|
22
|
+
<script type="module" src="{{ url_for('static', filename='js/create-balance-chart.js') }}">
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{% endblock %}
|
|
26
|
+
|
|
27
|
+
|
|
4
28
|
{% block header %}
|
|
5
29
|
|
|
6
30
|
<h1>
|
|
@@ -57,27 +81,3 @@
|
|
|
57
81
|
</div>
|
|
58
82
|
|
|
59
83
|
{% endblock %}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{% block javascript %}
|
|
63
|
-
|
|
64
|
-
<script>
|
|
65
|
-
const EXPAND_TRANSACTION_ENDPOINT = "{{ url_for('banking.expand_transaction') }}";
|
|
66
|
-
const LINKED_TRANSACTION_ENDPOINT = "{{ url_for('banking.show_linked_transaction') }}";
|
|
67
|
-
const LOAD_TRANSACTIONS_ENDPOINT = "{{ url_for('banking.load_more_transactions') }}";
|
|
68
|
-
const LOAD_TRANSACTIONS_SELECTORS = {
|
|
69
|
-
"account_id": {{ account.id }},
|
|
70
|
-
"block_count": 1
|
|
71
|
-
};
|
|
72
|
-
const BALANCE_CHART_DATA = {{ chart_data|tojson }};
|
|
73
|
-
</script>
|
|
74
|
-
<script type="module" src="{{ url_for('static', filename='js/load-more-transactions.js') }}">
|
|
75
|
-
</script>
|
|
76
|
-
<script type="module" src="{{ url_for('static', filename='js/expand-transaction.js') }}">
|
|
77
|
-
</script>
|
|
78
|
-
<script type="module" src="{{ url_for('static', filename='js/show-linked-transaction.js') }}">
|
|
79
|
-
</script>
|
|
80
|
-
<script type="module" src="{{ url_for('static', filename='js/create-balance-chart.js') }}">
|
|
81
|
-
</script>
|
|
82
|
-
|
|
83
|
-
{% endblock %}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{% extends 'layout.html' %}
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
{% block javascript %}
|
|
5
|
+
|
|
6
|
+
<script type="module" src="{{ url_for('static', filename='js/expand-bank-account.js') }}">
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
{% endblock %}
|
|
10
|
+
|
|
11
|
+
|
|
4
12
|
{% block header %}
|
|
5
13
|
|
|
6
14
|
<h1>
|
|
@@ -83,9 +91,3 @@
|
|
|
83
91
|
</div>
|
|
84
92
|
|
|
85
93
|
{% endblock %}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
{% block javascript %}
|
|
89
|
-
<script type="module" src="{{ url_for('static', filename='js/expand-bank-account.js') }}">
|
|
90
|
-
</script>
|
|
91
|
-
{% endblock %}
|