diff --git a/src/accounting/option/forms.py b/src/accounting/option/forms.py index 84bd70f..04531b1 100644 --- a/src/accounting/option/forms.py +++ b/src/accounting/option/forms.py @@ -209,8 +209,26 @@ class RecurringForm(RecurringItemForm): return (item.name.data, item.account_code.data, item.description_template.data) - return {"expense": [as_tuple(x.form) for x in self.expenses], - "income": [as_tuple(x.form) for x in self.incomes]} + expenses: list[RecurringItemForm] = [x.form for x in self.expenses] + self.__sort_item_forms(expenses) + incomes: list[RecurringItemForm] = [x.form for x in self.incomes] + self.__sort_item_forms(incomes) + return {"expense": [as_tuple(x) for x in expenses], + "income": [as_tuple(x) for x in incomes]} + + @staticmethod + def __sort_item_forms(forms: list[RecurringItemForm]) -> None: + """Sorts the recurring item sub-forms. + + :param forms: The recurring item sub-forms. + :return: None. + """ + ord_by_form: dict[RecurringItemForm, int] \ + = {forms[i]: i for i in range(len(forms))} + recv_no: set[int] = {x.no.data for x in forms if x.no.data is not None} + missing_recv_no: int = 100 if len(recv_no) == 0 else max(recv_no) + 100 + forms.sort(key=lambda x: (x.no.data or missing_recv_no, + ord_by_form.get(x))) class OptionForm(FlaskForm): diff --git a/src/accounting/static/js/option-form.js b/src/accounting/static/js/option-form.js index 8ed397f..1397568 100644 --- a/src/accounting/static/js/option-form.js +++ b/src/accounting/static/js/option-form.js @@ -236,6 +236,7 @@ class RecurringExpenseIncomeSubForm { this.#addButton = document.getElementById(this.#prefix + "-add"); this.#addButton.onclick = () => this.editor.onAddNew(); + this.#initializeDragAndDropReordering(); } /** @@ -252,6 +253,8 @@ class RecurringExpenseIncomeSubForm { const element = document.getElementById(this.#prefix + "-" + String(newIndex)) const item = new RecurringItemSubForm(this, element); this.#items.push(item); + this.#initializeDragAndDropReordering(); + this.validate(); return item; } @@ -265,6 +268,20 @@ class RecurringExpenseIncomeSubForm { this.#items.splice(index, 1); } + /** + * Initializes the drag and drop reordering on the recurring item sub-forms. + * + */ + #initializeDragAndDropReordering() { + initializeDragAndDropReordering(this.#itemList, () => { + const itemId = Array.from(this.#itemList.children).map((item) => item.id); + this.#items.sort((a, b) => itemId.indexOf(a.element.id) - itemId.indexOf(b.element.id)); + for (let i = 0; i < this.#items.length; i++) { + this.#items[i].no.value = String(i + 1); + } + }); + } + /** * Validates the form. * @@ -309,7 +326,7 @@ class RecurringItemSubForm { * The element * @type {HTMLLIElement} */ - #element; + element; /** * The item index @@ -329,6 +346,12 @@ class RecurringItemSubForm { */ #error; + /** + * The number + * @type {HTMLInputElement} + */ + no; + /** * The name input * @type {HTMLInputElement} @@ -379,11 +402,12 @@ class RecurringItemSubForm { */ constructor(expenseIncomeSubForm, element) { this.#expenseIncomeSubForm = expenseIncomeSubForm - this.#element = element; + this.element = element; this.itemIndex = parseInt(element.dataset.itemIndex); const prefix = "accounting-recurring-" + expenseIncomeSubForm.expenseIncome + "-" + element.dataset.itemIndex; this.#control = document.getElementById(prefix + "-control"); this.#error = document.getElementById(prefix + "-error"); + this.no = document.getElementById(prefix + "-no"); this.#name = document.getElementById(prefix + "-name"); this.#nameText = document.getElementById(prefix + "-name-text"); this.#accountCode = document.getElementById(prefix + "-account-code"); @@ -394,7 +418,7 @@ class RecurringItemSubForm { this.#control.onclick = () => this.#expenseIncomeSubForm.editor.onEdit(this); this.deleteButton.onclick = () => { - this.#element.parentElement.removeChild(this.#element); + this.element.parentElement.removeChild(this.element); this.#expenseIncomeSubForm.deleteItem(this); }; } diff --git a/src/accounting/templates/accounting/option/form.html b/src/accounting/templates/accounting/option/form.html index 7ae26a9..d3ca1d5 100644 --- a/src/accounting/templates/accounting/option/form.html +++ b/src/accounting/templates/accounting/option/form.html @@ -22,6 +22,7 @@ First written: 2023/3/22 {% extends "accounting/base.html" %} {% block accounting_scripts %} + {% endblock %}