create-categories #79
53
web/src/components/BudgetingCategory.vue
Normal file
53
web/src/components/BudgetingCategory.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { POST } from '../api';
|
||||
import { useBudgetsStore } from '../stores/budget';
|
||||
import { useAccountStore } from '../stores/budget-account';
|
||||
import { Category } from '../stores/category';
|
||||
import Currency from './Currency.vue'
|
||||
import Input from './Input.vue';
|
||||
|
||||
const props = defineProps<{category:Category, year: number, month: number}>()
|
||||
|
||||
const assigned = ref(props.category.Assigned);
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
|
||||
const budgetsStore = useBudgetsStore();
|
||||
const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID);
|
||||
|
||||
function assignedChanged(_e : Event, category : Category){
|
||||
POST("/budget/"+CurrentBudgetID.value+"/category/" + category.ID + "/" + props.year + "/" + (props.month+1),
|
||||
JSON.stringify({Assigned: assigned.value}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<template
|
||||
v-for="category in getCategoriesForGroup(group)"
|
||||
:key="category.ID"
|
||||
>
|
||||
<div
|
||||
class="contents"
|
||||
>
|
||||
<span
|
||||
class="whitespace-nowrap overflow-hidden"
|
||||
>{{ category.Name }}</span>
|
||||
<Currency
|
||||
:value="category.AvailableLastMonth"
|
||||
class="hidden lg:block"
|
||||
/>
|
||||
<Input
|
||||
v-model="assigned"
|
||||
type="number"
|
||||
class="hidden sm:block mx-2 text-right"
|
||||
@input="(evt : Event) => assignedChanged(evt, category)"
|
||||
/>
|
||||
<Currency
|
||||
:value="category.Activity"
|
||||
class="hidden sm:block"
|
||||
/>
|
||||
<Currency
|
||||
:value="accountStore.GetCategoryAvailable(category)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
66
web/src/components/BudgetingCategoryGroup.vue
Normal file
66
web/src/components/BudgetingCategoryGroup.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useCategoryStore } from '../stores/category';
|
||||
import { CategoryGroup } from '../stores/category-group';
|
||||
import BudgetingCategory from './BudgetingCategory.vue';
|
||||
import Currency from './Currency.vue'
|
||||
import CreateCategory from '../dialogs/CreateCategory.vue';
|
||||
|
||||
const props = defineProps<{group: CategoryGroup, year: number, month: number}>();
|
||||
|
||||
const categoryStore = useCategoryStore();
|
||||
const categoriesForGroup = categoryStore.GetCategoriesForGroup(props.group);
|
||||
|
||||
const expanded = ref(true)
|
||||
function toggleGroup() {
|
||||
expanded.value = !expanded.value;
|
||||
}
|
||||
|
||||
const availableLastMonth = computed(() => categoriesForGroup.reduce((prev, current) => prev + current.AvailableLastMonth, 0))
|
||||
const assigned = computed(() => categoriesForGroup.reduce((prev, current) => prev + current.Assigned, 0))
|
||||
const activity = computed(() => categoriesForGroup.reduce((prev, current) => prev + current.Activity, 0))
|
||||
const available = computed(() => activity.value+assigned.value+availableLastMonth.value);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
class="text-lg font-bold mt-2"
|
||||
@click="toggleGroup()"
|
||||
>{{ (expanded ? "−" : "+") + " " + group.Name }}
|
||||
<CreateCategory :category-group="group.Name" />
|
||||
</span>
|
||||
<Currency
|
||||
:value="availableLastMonth"
|
||||
class="hidden lg:block mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<Currency
|
||||
:value="assigned"
|
||||
class="hidden sm:block mx-2 mt-2 text-right"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<Currency
|
||||
:value="activity"
|
||||
class="hidden sm:block mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<Currency
|
||||
:value="available"
|
||||
class="mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<template
|
||||
v-if="expanded">
|
||||
<BudgetingCategory
|
||||
v-for="category in categoriesForGroup"
|
||||
:key="category.ID"
|
||||
:category="category"
|
||||
:year="year"
|
||||
:month="month"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
@ -1,17 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watchEffect } from "vue";
|
||||
import Currency from "../components/Currency.vue";
|
||||
import { computed, onMounted, watchEffect } from "vue";
|
||||
import { useBudgetsStore } from "../stores/budget";
|
||||
import { useCategoryGroupStore, CategoryGroup } from "../stores/category-group";
|
||||
import { useCategoryStore } from "../stores/category";
|
||||
import { useCategoryGroupStore } from "../stores/category-group";
|
||||
import { useAccountStore } from "../stores/budget-account";
|
||||
import { useSessionStore } from "../stores/session";
|
||||
import Input from "../components/Input.vue";
|
||||
import { POST } from "../api";
|
||||
import CreateCategory from "../dialogs/CreateCategory.vue";
|
||||
import BudgetingSummary from "../components/BudgetingSummary.vue";
|
||||
import { Category } from "../stores/category";
|
||||
import CreateCategoryGroup from "../dialogs/CreateCategoryGroup.vue";
|
||||
import BudgetingCategoryGroup from "../components/BudgetingCategoryGroup.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
budgetid: string,
|
||||
@ -22,21 +19,9 @@ const props = defineProps<{
|
||||
const categoryGroupStore = useCategoryGroupStore()
|
||||
const categoryGroups = computed(() => [...categoryGroupStore.CategoryGroups.values()]);
|
||||
|
||||
const categoryStore = useCategoryStore();
|
||||
function getCategoriesForGroup(group : CategoryGroup) {
|
||||
return categoryStore.GetCategoriesForGroup(group);
|
||||
}
|
||||
|
||||
const budgetsStore = useBudgetsStore();
|
||||
const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID);
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
const categoriesForMonth = accountStore.CategoriesForMonthAndGroup;
|
||||
|
||||
function GetCategories(group: string) {
|
||||
return [...categoriesForMonth(selected.value.Year, selected.value.Month, group)];
|
||||
};
|
||||
|
||||
const previous = computed(() => ({
|
||||
Year: new Date(selected.value.Year, selected.value.Month - 1, 1).getFullYear(),
|
||||
Month: new Date(selected.value.Year, selected.value.Month - 1, 1).getMonth(),
|
||||
@ -63,20 +48,6 @@ onMounted(() => {
|
||||
useSessionStore().setTitle("Budget for " + selected.value.Month + "/" + selected.value.Year);
|
||||
})
|
||||
|
||||
const expandedGroups = ref<Map<string, boolean>>(new Map<string, boolean>())
|
||||
|
||||
function toggleGroup(group: { Name: string, Expand: boolean }) {
|
||||
expandedGroups.value.set(group.Name, !(expandedGroups.value.get(group.Name) ?? group.Expand))
|
||||
}
|
||||
|
||||
function getGroupState(group: { Name: string, Expand: boolean }): boolean {
|
||||
return expandedGroups.value.get(group.Name) ?? group.Expand;
|
||||
}
|
||||
|
||||
function assignedChanged(_e : Event, category : Category){
|
||||
POST("/budget/"+CurrentBudgetID.value+"/category/" + category.ID + "/" + selected.value.Year + "/" + (selected.value.Month+1),
|
||||
JSON.stringify({Assigned: category.Assigned}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -107,71 +78,13 @@ function assignedChanged(_e : Event, category : Category){
|
||||
<span class="hidden sm:block text-right">Assigned</span>
|
||||
<span class="hidden sm:block text-right">Activity</span>
|
||||
<span class="hidden sm:block text-right">Available</span>
|
||||
<template
|
||||
<BudgetingCategoryGroup
|
||||
v-for="group in categoryGroups"
|
||||
:key="group.Name"
|
||||
>
|
||||
<span
|
||||
class="text-lg font-bold mt-2"
|
||||
@click="toggleGroup(group)"
|
||||
>{{ (getGroupState(group) ? "−" : "+") + " " + group.Name }}
|
||||
<CreateCategory :category-group="group.Name" />
|
||||
</span>
|
||||
<Currency
|
||||
:value="group.AvailableLastMonth"
|
||||
class="hidden lg:block mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
:group="group"
|
||||
:year="selected.Year"
|
||||
:month="selected.Month"
|
||||
/>
|
||||
<Currency
|
||||
:value="group.Assigned"
|
||||
class="hidden sm:block mx-2 mt-2 text-right"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<Currency
|
||||
:value="group.Activity"
|
||||
class="hidden sm:block mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<Currency
|
||||
:value="group.Available"
|
||||
class="mt-2"
|
||||
positive-class="text-slate-500"
|
||||
negative-class="text-red-700 dark:text-red-400"
|
||||
/>
|
||||
<template
|
||||
v-for="category in getCategoriesForGroup(group)"
|
||||
:key="category.ID"
|
||||
>
|
||||
<div
|
||||
v-if="getGroupState(group)"
|
||||
class="contents"
|
||||
>
|
||||
<span
|
||||
class="whitespace-nowrap overflow-hidden"
|
||||
>{{ category.Name }}</span>
|
||||
<Currency
|
||||
:value="category.AvailableLastMonth"
|
||||
class="hidden lg:block"
|
||||
/>
|
||||
<Input
|
||||
v-model="category.Assigned"
|
||||
type="number"
|
||||
class="hidden sm:block mx-2 text-right"
|
||||
@input="(evt : Event) => assignedChanged(evt, category)"
|
||||
/>
|
||||
<Currency
|
||||
:value="category.Activity"
|
||||
class="hidden sm:block"
|
||||
/>
|
||||
<Currency
|
||||
:value="accountStore.GetCategoryAvailable(category)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<CreateCategoryGroup />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -120,15 +120,10 @@ export const useAccountStore = defineStore("budget/account", {
|
||||
Expand: prev.Name != "Hidden Categories",
|
||||
});
|
||||
} else {
|
||||
categoryGroups[categoryGroups.length - 1].Available +=
|
||||
this.GetCategoryAvailable(category);
|
||||
categoryGroups[
|
||||
categoryGroups.length - 1
|
||||
].AvailableLastMonth += category.AvailableLastMonth;
|
||||
categoryGroups[categoryGroups.length - 1].Activity +=
|
||||
category.Activity;
|
||||
categoryGroups[categoryGroups.length - 1].Assigned +=
|
||||
category.Assigned;
|
||||
categoryGroups[categoryGroups.length - 1].Available += this.GetCategoryAvailable(category);
|
||||
categoryGroups[categoryGroups.length - 1].AvailableLastMonth += category.AvailableLastMonth;
|
||||
categoryGroups[categoryGroups.length - 1].Activity += category.Activity;
|
||||
categoryGroups[categoryGroups.length - 1].Assigned += category.Assigned;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user