Improve new components
This commit is contained in:
parent
94c2465109
commit
31a4135f2e
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>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref, watchEffect } from "vue";
|
import { computed, onMounted, watchEffect } from "vue";
|
||||||
import Currency from "../components/Currency.vue";
|
|
||||||
import { useBudgetsStore } from "../stores/budget";
|
import { useBudgetsStore } from "../stores/budget";
|
||||||
import { useCategoryGroupStore, CategoryGroup } from "../stores/category-group";
|
import { useCategoryGroupStore } from "../stores/category-group";
|
||||||
import { useCategoryStore } from "../stores/category";
|
|
||||||
import { useAccountStore } from "../stores/budget-account";
|
import { useAccountStore } from "../stores/budget-account";
|
||||||
import { useSessionStore } from "../stores/session";
|
import { useSessionStore } from "../stores/session";
|
||||||
import Input from "../components/Input.vue";
|
|
||||||
import { POST } from "../api";
|
import { POST } from "../api";
|
||||||
import CreateCategory from "../dialogs/CreateCategory.vue";
|
|
||||||
import BudgetingSummary from "../components/BudgetingSummary.vue";
|
import BudgetingSummary from "../components/BudgetingSummary.vue";
|
||||||
import { Category } from "../stores/category";
|
import { Category } from "../stores/category";
|
||||||
import CreateCategoryGroup from "../dialogs/CreateCategoryGroup.vue";
|
import CreateCategoryGroup from "../dialogs/CreateCategoryGroup.vue";
|
||||||
|
import BudgetingCategoryGroup from "../components/BudgetingCategoryGroup.vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
budgetid: string,
|
budgetid: string,
|
||||||
@ -22,21 +19,9 @@ const props = defineProps<{
|
|||||||
const categoryGroupStore = useCategoryGroupStore()
|
const categoryGroupStore = useCategoryGroupStore()
|
||||||
const categoryGroups = computed(() => [...categoryGroupStore.CategoryGroups.values()]);
|
const categoryGroups = computed(() => [...categoryGroupStore.CategoryGroups.values()]);
|
||||||
|
|
||||||
const categoryStore = useCategoryStore();
|
|
||||||
function getCategoriesForGroup(group : CategoryGroup) {
|
|
||||||
return categoryStore.GetCategoriesForGroup(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
const budgetsStore = useBudgetsStore();
|
const budgetsStore = useBudgetsStore();
|
||||||
const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID);
|
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(() => ({
|
const previous = computed(() => ({
|
||||||
Year: new Date(selected.value.Year, selected.value.Month - 1, 1).getFullYear(),
|
Year: new Date(selected.value.Year, selected.value.Month - 1, 1).getFullYear(),
|
||||||
Month: new Date(selected.value.Year, selected.value.Month - 1, 1).getMonth(),
|
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);
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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">Assigned</span>
|
||||||
<span class="hidden sm:block text-right">Activity</span>
|
<span class="hidden sm:block text-right">Activity</span>
|
||||||
<span class="hidden sm:block text-right">Available</span>
|
<span class="hidden sm:block text-right">Available</span>
|
||||||
<template
|
<BudgetingCategoryGroup
|
||||||
v-for="group in categoryGroups"
|
v-for="group in categoryGroups"
|
||||||
:key="group.Name"
|
:key="group.Name"
|
||||||
>
|
:group="group"
|
||||||
<span
|
:year="selected.Year"
|
||||||
class="text-lg font-bold mt-2"
|
:month="selected.Month"
|
||||||
@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"
|
|
||||||
/>
|
/>
|
||||||
<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 />
|
<CreateCategoryGroup />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -120,15 +120,10 @@ export const useAccountStore = defineStore("budget/account", {
|
|||||||
Expand: prev.Name != "Hidden Categories",
|
Expand: prev.Name != "Hidden Categories",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
categoryGroups[categoryGroups.length - 1].Available +=
|
categoryGroups[categoryGroups.length - 1].Available += this.GetCategoryAvailable(category);
|
||||||
this.GetCategoryAvailable(category);
|
categoryGroups[categoryGroups.length - 1].AvailableLastMonth += category.AvailableLastMonth;
|
||||||
categoryGroups[
|
categoryGroups[categoryGroups.length - 1].Activity += category.Activity;
|
||||||
categoryGroups.length - 1
|
categoryGroups[categoryGroups.length - 1].Assigned += category.Assigned;
|
||||||
].AvailableLastMonth += category.AvailableLastMonth;
|
|
||||||
categoryGroups[categoryGroups.length - 1].Activity +=
|
|
||||||
category.Activity;
|
|
||||||
categoryGroups[categoryGroups.length - 1].Assigned +=
|
|
||||||
category.Assigned;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user