diff --git a/web-app/src/api/transaction.ts b/web-app/src/api/transaction.ts index 07a8ad2..aac8dc8 100644 --- a/web-app/src/api/transaction.ts +++ b/web-app/src/api/transaction.ts @@ -165,6 +165,20 @@ export class TransactionApiClient extends ApiClient { return super.getJson(this.path + '/categories') } + async getCategoriesFlattened(): Promise { + const categories = await this.getCategories() + const flat: TransactionCategoryTree[] = [] + await this.flattenCategories(flat, categories) + return flat + } + + private flattenCategories(arr: TransactionCategoryTree[], tree: TransactionCategoryTree[]) { + for (const category of tree) { + arr.push(category) + this.flattenCategories(arr, category.children) + } + } + getCategory(id: number): Promise { return super.getJson(this.path + '/categories/' + id) } diff --git a/web-app/src/components/CategorySelect.vue b/web-app/src/components/CategorySelect.vue new file mode 100644 index 0000000..b665b71 --- /dev/null +++ b/web-app/src/components/CategorySelect.vue @@ -0,0 +1,31 @@ + + diff --git a/web-app/src/components/EditCategoryModal.vue b/web-app/src/components/EditCategoryModal.vue index fc75d3d..292b219 100644 --- a/web-app/src/components/EditCategoryModal.vue +++ b/web-app/src/components/EditCategoryModal.vue @@ -6,6 +6,7 @@ import AppForm from './form/AppForm.vue'; import FormGroup from './form/FormGroup.vue'; import FormControl from './form/FormControl.vue'; import AppButton from './AppButton.vue'; +import CategorySelect from './CategorySelect.vue'; const props = defineProps<{ category?: TransactionCategory @@ -24,11 +25,16 @@ function show(): Promise { name.value = props.category?.name ?? '' description.value = props.category?.description ?? '' if (props.category) { + name.value = props.category.name + description.value = props.category.description color.value = '#' + props.category.color + parentId.value = props.category.parentId } else { + name.value = '' + description.value = '' color.value = '#ffffff' + parentId.value = null } - parentId.value = props.category?.parentId ?? null return modal.value.show() } @@ -85,6 +91,9 @@ defineExpose({ show }) + + + diff --git a/web-app/src/components/LineItemsEditor.vue b/web-app/src/components/LineItemsEditor.vue index 5bd522b..5f49d76 100644 --- a/web-app/src/components/LineItemsEditor.vue +++ b/web-app/src/components/LineItemsEditor.vue @@ -11,20 +11,20 @@ import { formatMoney, type Currency } from '@/api/data'; import ModalWrapper from './ModalWrapper.vue'; import FormControl from './form/FormControl.vue'; import { ref, type Ref, useTemplateRef } from 'vue'; +import CategorySelect from './CategorySelect.vue'; const model = defineModel({ required: true }) defineProps<{ - currency: Currency | null, - categories: TransactionCategoryTree[] + currency: Currency | null }>() const addLineItemDescription = ref('') const addLineItemValuePerItem = ref(0) const addLineItemQuantity = ref(0) -const addLineItemCategory: Ref = ref(null) +const addLineItemCategoryId: Ref = ref(null) +const selectedCategory: Ref = ref(null) const addLineItemModal = useTemplateRef('addLineItemModal') - function canAddLineItem() { return addLineItemDescription.value.length > 0 && addLineItemQuantity.value > 0 @@ -34,11 +34,11 @@ function showAddLineItemModal() { addLineItemDescription.value = '' addLineItemValuePerItem.value = 1.00 addLineItemQuantity.value = 1 - addLineItemCategory.value = null + addLineItemCategoryId.value = null addLineItemModal.value?.show() } -function addLineItem() { +async function addLineItem() { const idxs: number[] = model.value.map(i => i.idx) const newIdx = Math.max(...idxs) model.value.push({ @@ -46,7 +46,7 @@ function addLineItem() { description: addLineItemDescription.value, quantity: addLineItemQuantity.value, valuePerItem: addLineItemValuePerItem.value, - category: addLineItemCategory.value + category: selectedCategory.value }) addLineItemModal.value?.close() } @@ -104,12 +104,7 @@ function removeLineItem(idx: number) { - + diff --git a/web-app/src/pages/CategoriesPage.vue b/web-app/src/pages/CategoriesPage.vue index 4f16aa2..6e87df5 100644 --- a/web-app/src/pages/CategoriesPage.vue +++ b/web-app/src/pages/CategoriesPage.vue @@ -54,6 +54,7 @@ async function deleteCategory(categoryId: number) { async function addCategory() { editedCategory.value = undefined + await nextTick() const result = await editCategoryModal.value?.show() if (result === 'saved') { await loadCategories() diff --git a/web-app/src/pages/forms/EditTransactionPage.vue b/web-app/src/pages/forms/EditTransactionPage.vue index 6837be2..2c5d395 100644 --- a/web-app/src/pages/forms/EditTransactionPage.vue +++ b/web-app/src/pages/forms/EditTransactionPage.vue @@ -12,8 +12,9 @@ The form consists of a few main sections: