Convert other pages to composition API

This commit is contained in:
Jan Bader 2022-02-14 22:24:42 +00:00
parent d11c0036b5
commit 0a030eaee1
9 changed files with 196 additions and 231 deletions

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref } from "vue"
import { computed, ref } from "vue"
import Autocomplete, { Suggestion } from '../components/Autocomplete.vue'
import Currency from "../components/Currency.vue";
import TransactionRow from "../components/TransactionRow.vue";
@ -22,10 +22,10 @@ function saveTransaction(e: MouseEvent) {
POST("/transaction/new", JSON.stringify({
budget_id: props.budgetid,
account_id: props.accountid,
date: TransactionDate,
payee: Payee,
category: Category,
memo: Memo,
date: TransactionDate.value,
payee: Payee.value,
category: Category.value,
memo: Memo.value,
amount: Amount,
state: "Uncleared"
}))

View File

@ -1,10 +1,8 @@
<script lang="ts">
import { defineComponent } from "vue";
<script lang="ts" setup>
import { onMounted } from 'vue';
export default defineComponent({
mounted() {
document.title = "Budgeteer - Admin";
},
onMounted(() => {
document.title = "Budgeteer - Admin";
})
</script>

View File

@ -1,20 +1,25 @@
<script lang="ts">
import { mapState } from "pinia"
import { defineComponent } from "vue"
<script lang="ts" setup>
import Currency from "../components/Currency.vue"
import { useBudgetsStore } from "../stores/budget"
import { useAccountStore } from "../stores/budget-account"
import { useSettingsStore } from "../stores/settings"
export default defineComponent({
props: ["budgetid", "accountid"],
components: { Currency },
computed: {
...mapState(useSettingsStore, ["ExpandMenu"]),
...mapState(useBudgetsStore, ["CurrentBudgetName", "CurrentBudgetID"]),
...mapState(useAccountStore, ["OnBudgetAccounts", "OnBudgetAccountsBalance", "OffBudgetAccounts", "OffBudgetAccountsBalance"])
}
})
const props = defineProps<{
budgetid: string,
accountid: string,
}>();
const ExpandMenu = useSettingsStore().Menu.Expand;
const budgetStore = useBudgetsStore();
const CurrentBudgetName = budgetStore.CurrentBudgetName;
const CurrentBudgetID = budgetStore.CurrentBudgetID;
const accountStore = useAccountStore();
const OnBudgetAccounts = accountStore.OnBudgetAccounts;
const OffBudgetAccounts = accountStore.OffBudgetAccounts;
const OnBudgetAccountsBalance = accountStore.OnBudgetAccountsBalance;
const OffBudgetAccountsBalance = accountStore.OffBudgetAccountsBalance;
</script>
<template>

View File

@ -1,68 +1,55 @@
<script lang="ts">
import { mapState } from "pinia";
import { defineComponent, PropType } from "vue";
<script lang="ts" setup>
import { computed, defineProps, onMounted, PropType, watch, watchEffect } from "vue";
import Currency from "../components/Currency.vue";
import { useBudgetsStore } from "../stores/budget";
import { Category, useAccountStore } from "../stores/budget-account";
import { useAccountStore } from "../stores/budget-account";
interface Date {
Year: number,
Month: number,
}
export default defineComponent({
props: {
budgetid: {} as PropType<string>,
year: {} as PropType<number>,
month: {} as PropType<number>,
},
computed: {
...mapState(useBudgetsStore, ["CurrentBudgetID"]),
Categories() : Category[] {
const accountStore = useAccountStore();
return [...accountStore.CategoriesForMonth(this.selected.Year, this.selected.Month)];
},
previous() : Date {
return {
Year: new Date(this.selected.Year, this.selected.Month - 1, 1).getFullYear(),
Month: new Date(this.selected.Year, this.selected.Month - 1, 1).getMonth(),
};
},
current() : Date {
return {
Year: new Date().getFullYear(),
Month: new Date().getMonth(),
};
},
selected() : Date {
return {
Year: this.year ?? this.current.Year,
Month: Number(this.month ?? this.current.Month) + 1
}
},
next() : Date {
return {
Year: new Date(this.selected.Year, Number(this.month) + 1, 1).getFullYear(),
Month: new Date(this.selected.Year, Number(this.month) + 1, 1).getMonth(),
};
}
},
mounted() : Promise<void> {
document.title = "Budgeteer - Budget for " + this.selected.Month + "/" + this.selected.Year;
return useAccountStore().FetchMonthBudget(this.budgetid ?? "", this.selected.Year, this.selected.Month);
},
watch: {
year() {
if (this.year != undefined && this.month != undefined)
return useAccountStore().FetchMonthBudget(this.budgetid ?? "", this.year, this.month);
},
month() {
if (this.year != undefined && this.month != undefined)
return useAccountStore().FetchMonthBudget(this.budgetid ?? "", this.year, this.month);
},
},
components: { Currency }
})
const props = defineProps<{
budgetid: string,
year: string,
month: string,
}>()
const budgetsStore = useBudgetsStore();
const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID);
const accountStore = useAccountStore();
//const categoriesForMonth = accountStore.CategoriesForMonth;
const Categories = computed(() => {
const yearMap = accountStore.Months.get(selected.value.Year);
const monthMap = yearMap?.get(selected.value.Month);
console.log("MTH", monthMap)
const CategoriesForMonth = [ ...monthMap?.values() || [] ];
console.log("YAY?")
return CategoriesForMonth;
//return [...categoriesForMonth(selected.value.Year, selected.value.Month)];
});
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(),
}));
const current = computed(() => ({
Year: new Date().getFullYear(),
Month: new Date().getMonth(),
}));
const selected = computed(() => ({
Year: Number(props.year) ?? current.value.Year,
Month: Number(props.month ?? current.value.Month) + 1
}));
const next = computed(() => ({
Year: new Date(selected.value.Year, Number(props.month) + 1, 1).getFullYear(),
Month: new Date(selected.value.Year, Number(props.month) + 1, 1).getMonth(),
}));
watchEffect(() => {
if (props.year != undefined && props.month != undefined)
return useAccountStore().FetchMonthBudget(props.budgetid ?? "", Number(props.year), Number(props.month));
});
/*{{define "title"}}
{{printf "Budget for %s %d" .Date.Month .Date.Year}}

View File

@ -1,17 +1,13 @@
<script lang="ts">
<script lang="ts" setup>
import NewBudget from '../dialogs/NewBudget.vue';
import Card from '../components/Card.vue';
import { defineComponent } from 'vue';
import { mapState } from 'pinia';
import { useSessionStore } from '../stores/session';
export default defineComponent({
props: ["budgetid"],
components: { NewBudget, Card },
computed: {
...mapState(useSessionStore, ["BudgetsList"]),
}
})
const props = defineProps<{
budgetid: string,
}>();
const BudgetsList = useSessionStore().BudgetsList;
</script>
<template>

View File

@ -1,9 +1,4 @@
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
})
<script lang="ts" setup>
</script>
<template>

View File

@ -1,46 +1,48 @@
<script lang="ts">
import { defineComponent } from "vue";
<script lang="ts" setup>
import { onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import { useSessionStore } from "../stores/session";
export default defineComponent({
data() {
return {
error: "",
login: {
user: "",
password: ""
},
showPassword: false
}
},
mounted() {
document.title = "Budgeteer - Login";
},
methods: {
formSubmit(e : MouseEvent) {
e.preventDefault();
useSessionStore().login(this.$data.login)
.then(x => {
this.$data.error = "";
this.$router.replace("/dashboard");
})
.catch(x => this.$data.error = "The entered credentials are invalid!");
const error = ref("");
const login = ref({ user: "", password: "" });
// TODO display invalidCredentials
// TODO redirect to dashboard on success
}
}
})
onMounted(() => {
document.title = "Budgeteer - Login";
});
function formSubmit(e: MouseEvent) {
e.preventDefault();
useSessionStore().login(login)
.then(x => {
error.value = "";
useRouter().replace("/dashboard");
})
.catch(x => error.value = "The entered credentials are invalid!");
// TODO display invalidCredentials
// TODO redirect to dashboard on success
}
</script>
<template>
<div>
<input type="text" v-model="login.user" placeholder="Username" class="border-2 border-black rounded-lg block px-2 my-2 w-48" />
<input type="password" v-model="login.password" placeholder="Password" class="border-2 border-black rounded-lg block px-2 my-2 w-48" />
</div>
<div>{{ error }}</div>
<button type="submit" @click="formSubmit" class="bg-blue-300 rounded-lg p-2 w-48">Login</button>
<p>
New user? <router-link to="/register">Register</router-link> instead!
</p>
<div>
<input
type="text"
v-model="login.user"
placeholder="Username"
class="border-2 border-black rounded-lg block px-2 my-2 w-48"
/>
<input
type="password"
v-model="login.password"
placeholder="Password"
class="border-2 border-black rounded-lg block px-2 my-2 w-48"
/>
</div>
<div>{{ error }}</div>
<button type="submit" @click="formSubmit" class="bg-blue-300 rounded-lg p-2 w-48">Login</button>
<p>
New user?
<router-link to="/register">Register</router-link>instead!
</p>
</template>

View File

@ -1,31 +1,20 @@
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
import { useSessionStore } from '../stores/session';
export default defineComponent({
data() {
return {
showPassword: false,
error: "",
login: {
email: "",
password: "",
name: "",
}
}
},
methods: {
formSubmit (e : FormDataEvent) {
e.preventDefault();
useSessionStore().register(this.$data.login)
.then(() => this.$data.error = "")
.catch(() => this.$data.error = "Something went wrong!");
const error = ref("");
const login = ref({ email: "", password: "", name: "" });
const showPassword = ref(false);
// TODO display invalidCredentials
// TODO redirect to dashboard on success
}
}
})
function formSubmit(e: FormDataEvent) {
e.preventDefault();
useSessionStore().register(login)
.then(() => error.value = "")
.catch(() => error.value = "Something went wrong!");
// TODO display invalidCredentials
// TODO redirect to dashboard on success
}
</script>
<template>
@ -38,30 +27,35 @@ export default defineComponent({
<v-text-field v-model="login.name" type="text" label="Name" />
</v-col>
<v-col cols="6">
<v-text-field v-model="login.password" label="Password"
<v-text-field
v-model="login.password"
label="Password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = showPassword"
:error-message="error"
error-count="2"
error />
error
/>
</v-col>
<v-col cols="6">
<v-text-field v-model="login.password" label="Repeat password"
<v-text-field
v-model="login.password"
label="Repeat password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = showPassword"
:error-message="error"
error-count="2"
error />
error
/>
</v-col>
</v-row>
<div class="form-group">
{{ error }}
</div>
<div class="form-group">{{ error }}</div>
<v-btn type="submit" @click="formSubmit">Register</v-btn>
<p>
Existing user? <router-link to="/login">Login</router-link> instead!
</p>
<p>
Existing user?
<router-link to="/login">Login</router-link>instead!
</p>
</v-container>
</template>

View File

@ -1,65 +1,56 @@
<script lang="ts">
import { defineComponent } from "vue"
<script lang="ts" setup>
import { computed, defineComponent, onMounted, ref } from "vue"
import { useRouter } from "vue-router";
import { DELETE, POST } from "../api";
import { useBudgetsStore } from "../stores/budget";
import { useSessionStore } from "../stores/session";
export default defineComponent({
data() {
return {
transactionsFile: undefined as File | undefined,
assignmentsFile: undefined as File | undefined
}
},
computed: {
filesIncomplete() : boolean {
return this.$data.transactionsFile == undefined || this.$data.assignmentsFile == undefined;
}
},
mounted() {
document.title = "Budgeteer - Settings";
},
methods: {
gotAssignments(e : Event) {
const input = (<HTMLInputElement>e.target);
if(input.files != null)
this.$data.assignmentsFile = input.files[0];
},
gotTransactions(e : Event) {
const input = (<HTMLInputElement>e.target);
if(input.files != null)
this.$data.transactionsFile = input.files[0];
},
deleteBudget() {
const currentBudgetID = useBudgetsStore().CurrentBudgetID;
if (currentBudgetID == null)
return;
const transactionsFile = ref<File | undefined>(undefined);
const assignmentsFile = ref<File | undefined>(undefined);
DELETE("/budget/" + currentBudgetID);
const filesIncomplete = computed(() => transactionsFile.value == undefined || assignmentsFile.value == undefined);
onMounted(() => {
document.title = "Budgeteer - Settings";
});
const budgetStore = useSessionStore();
budgetStore.Budgets.delete(currentBudgetID);
this.$router.push("/")
},
clearBudget() {
const currentBudgetID = useBudgetsStore().CurrentBudgetID;
POST("/budget/" + currentBudgetID + "/settings/clear", null)
},
cleanNegative() {
// <a href="/budget/{{.Budget.ID}}/settings/clean-negative">Fix all historic negative category-balances</a>
},
ynabImport() {
if (this.$data.transactionsFile == undefined || this.$data.assignmentsFile == undefined)
return
function gotAssignments(e: Event) {
const input = (<HTMLInputElement>e.target);
if (input.files != null)
assignmentsFile.value = input.files[0];
}
function gotTransactions(e: Event) {
const input = (<HTMLInputElement>e.target);
if (input.files != null)
transactionsFile.value = input.files[0];
};
function deleteBudget() {
const currentBudgetID = useBudgetsStore().CurrentBudgetID;
if (currentBudgetID == null)
return;
let formData = new FormData();
formData.append("transactions", this.$data.transactionsFile);
formData.append("assignments", this.$data.assignmentsFile);
const budgetStore = useBudgetsStore();
budgetStore.ImportYNAB(formData);
}
}
})
DELETE("/budget/" + currentBudgetID);
const budgetStore = useSessionStore();
budgetStore.Budgets.delete(currentBudgetID);
useRouter().push("/")
};
function clearBudget() {
const currentBudgetID = useBudgetsStore().CurrentBudgetID;
POST("/budget/" + currentBudgetID + "/settings/clear", null)
};
function cleanNegative() {
// <a href="/budget/{{.Budget.ID}}/settings/clean-negative">Fix all historic negative category-balances</a>
};
function ynabImport() {
if (transactionsFile.value == undefined || assignmentsFile.value == undefined)
return
let formData = new FormData();
formData.append("transactions", transactionsFile.value);
formData.append("assignments", assignmentsFile.value);
const budgetStore = useBudgetsStore();
budgetStore.ImportYNAB(formData);
};
</script>
<template>
@ -124,10 +115,7 @@ export default defineComponent({
</label>
<v-card-actions class="justify-center">
<v-btn
:disabled="filesIncomplete"
@click="ynabImport"
>Importieren</v-btn>
<v-btn :disabled="filesIncomplete" @click="ynabImport">Importieren</v-btn>
</v-card-actions>
</v-card>
</v-col>