Clean up profile handling again!
This commit is contained in:
parent
a674421337
commit
074b4ded1d
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { type RouteLocation } from 'vue-router'
|
||||||
import { ApiClient } from './base'
|
import { ApiClient } from './base'
|
||||||
import type { Currency } from './data'
|
import type { Currency } from './data'
|
||||||
import type { Page, PageRequest } from './pagination'
|
import type { Page, PageRequest } from './pagination'
|
||||||
|
|
@ -125,9 +126,9 @@ export interface AccountHistoryJournalEntryItem extends AccountHistoryItem {
|
||||||
export class AccountApiClient extends ApiClient {
|
export class AccountApiClient extends ApiClient {
|
||||||
readonly path: string
|
readonly path: string
|
||||||
|
|
||||||
constructor() {
|
constructor(route: RouteLocation) {
|
||||||
super()
|
super()
|
||||||
this.path = `/profiles/${getSelectedProfile()}/accounts`
|
this.path = `/profiles/${getSelectedProfile(route)}/accounts`
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccounts(): Promise<Account[]> {
|
getAccounts(): Promise<Account[]> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useRoute, type RouteLocation } from 'vue-router'
|
import { type RouteLocation } from 'vue-router'
|
||||||
import { ApiClient } from './base'
|
import { ApiClient } from './base'
|
||||||
|
|
||||||
export interface Profile {
|
export interface Profile {
|
||||||
|
|
@ -35,11 +35,10 @@ export class ProfileApiClient extends ApiClient {
|
||||||
/**
|
/**
|
||||||
* Gets the currently selected profile. Throws an error in any case where
|
* Gets the currently selected profile. Throws an error in any case where
|
||||||
* the route doesn't contain profile name information.
|
* the route doesn't contain profile name information.
|
||||||
* @param route The route to get the profile from. Defaults to getting it from
|
* @param route The route to get the profile from.
|
||||||
* Vue's `useRoute()` which is available in component contexts.
|
|
||||||
* @returns The currently selected profile name, via the current route.
|
* @returns The currently selected profile name, via the current route.
|
||||||
*/
|
*/
|
||||||
export function getSelectedProfile(route: RouteLocation = useRoute()): string {
|
export function getSelectedProfile(route: RouteLocation): string {
|
||||||
if (!('profileName' in route.params)) {
|
if (!('profileName' in route.params)) {
|
||||||
throw new Error('No "profileName" route property available.')
|
throw new Error('No "profileName" route property available.')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { ApiClient } from './base'
|
import { ApiClient } from './base'
|
||||||
import type { Currency } from './data'
|
import type { Currency } from './data'
|
||||||
import { type Page, type PageRequest } from './pagination'
|
import { type Page, type PageRequest } from './pagination'
|
||||||
import { getSelectedProfile } from './profile'
|
|
||||||
|
|
||||||
export interface TransactionVendor {
|
export interface TransactionVendor {
|
||||||
id: number
|
id: number
|
||||||
|
|
@ -144,9 +143,9 @@ export interface CreateCategoryPayload {
|
||||||
export class TransactionApiClient extends ApiClient {
|
export class TransactionApiClient extends ApiClient {
|
||||||
readonly path: string
|
readonly path: string
|
||||||
|
|
||||||
constructor() {
|
constructor(profileName: string) {
|
||||||
super()
|
super()
|
||||||
this.path = `/profiles/${getSelectedProfile()}`
|
this.path = `/profiles/${profileName}`
|
||||||
}
|
}
|
||||||
|
|
||||||
getVendors(): Promise<TransactionVendor[]> {
|
getVendors(): Promise<TransactionVendor[]> {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ import AppButton from './AppButton.vue';
|
||||||
import { AccountApiClient, AccountValueRecordType, type Account, type AccountValueRecord, type AccountValueRecordCreationPayload } from '@/api/account';
|
import { AccountApiClient, AccountValueRecordType, type Account, type AccountValueRecord, type AccountValueRecordCreationPayload } from '@/api/account';
|
||||||
import { datetimeLocalToISO, getDatetimeLocalValueForNow } from '@/util/time';
|
import { datetimeLocalToISO, getDatetimeLocalValueForNow } from '@/util/time';
|
||||||
import FileSelector from './FileSelector.vue';
|
import FileSelector from './FileSelector.vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const props = defineProps<{ account: Account }>()
|
const props = defineProps<{ account: Account }>()
|
||||||
const modal = useTemplateRef('modal')
|
const modal = useTemplateRef('modal')
|
||||||
const savedValueRecord: Ref<AccountValueRecord | undefined> = ref(undefined)
|
const savedValueRecord: Ref<AccountValueRecord | undefined> = ref(undefined)
|
||||||
|
|
@ -36,7 +38,7 @@ async function addValueRecord() {
|
||||||
type: AccountValueRecordType.BALANCE,
|
type: AccountValueRecordType.BALANCE,
|
||||||
value: amount.value
|
value: amount.value
|
||||||
}
|
}
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
try {
|
try {
|
||||||
savedValueRecord.value = await api.createValueRecord(props.account.id, payload, attachments.value)
|
savedValueRecord.value = await api.createValueRecord(props.account.id, payload, attachments.value)
|
||||||
modal.value?.close('saved')
|
modal.value?.close('saved')
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,35 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
buttonStyle?: string,
|
export type ButtonTheme = "primary" | "secondary"
|
||||||
|
export type ButtonType = "button" | "submit" | "reset"
|
||||||
|
export type ButtonSize = "sm" | "md" | "lg"
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
theme?: ButtonTheme,
|
||||||
|
size?: ButtonSize,
|
||||||
icon?: string,
|
icon?: string,
|
||||||
buttonType?: "button" | "submit" | "reset" | undefined,
|
type?: ButtonType,
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}>()
|
}
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
buttonStyle: "primary",
|
||||||
|
buttonType: "button",
|
||||||
|
size: "md",
|
||||||
|
disabled: false
|
||||||
|
})
|
||||||
defineEmits(['click'])
|
defineEmits(['click'])
|
||||||
|
|
||||||
|
const buttonStyle = computed(() => ({
|
||||||
|
'app-button-theme-secondary': props.theme === "secondary",
|
||||||
|
'app-button-disabled': props.disabled,
|
||||||
|
'app-button-size-sm': props.size === "sm",
|
||||||
|
'app-button-size-lg': props.size === "lg"
|
||||||
|
}))
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<button class="app-button"
|
<button class="app-button" :class="buttonStyle" :type="type" :disabled="disabled" @click="$emit('click')">
|
||||||
:class="{ 'app-button-secondary': buttonStyle === 'secondary', 'app-button-disabled': disabled ?? false }"
|
|
||||||
@click="$emit('click')" :type="buttonType" :disabled="disabled ?? false">
|
|
||||||
<span v-if="icon">
|
<span v-if="icon">
|
||||||
<font-awesome-icon :icon="'fa-' + icon"
|
<font-awesome-icon :icon="'fa-' + icon"
|
||||||
:class="{ 'app-button-icon-with-text': $slots.default !== undefined, 'app-button-icon-without-text': $slots.default === undefined }"></font-awesome-icon>
|
:class="{ 'app-button-icon-with-text': $slots.default !== undefined, 'app-button-icon-without-text': $slots.default === undefined }"></font-awesome-icon>
|
||||||
|
|
@ -51,6 +69,17 @@ defineEmits(['click'])
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-button-size-sm {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-button-size-lg {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.app-button:hover:not(.app-button-disabled) {
|
.app-button:hover:not(.app-button-disabled) {
|
||||||
background-color: #374151;
|
background-color: #374151;
|
||||||
}
|
}
|
||||||
|
|
@ -65,13 +94,7 @@ defineEmits(['click'])
|
||||||
background-color: #3b4968;
|
background-color: #3b4968;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
.app-button-theme-secondary {
|
||||||
.app-button {
|
|
||||||
padding: .75rem 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-button-secondary {
|
|
||||||
background-color: #1d2330;
|
background-color: #1d2330;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getSelectedProfile } from '@/api/profile';
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
import type { TransactionCategory } from '@/api/transaction';
|
import type { TransactionCategory } from '@/api/transaction';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const props = defineProps<{ category: TransactionCategory, clickable?: boolean }>()
|
const props = defineProps<{ category: TransactionCategory, clickable?: boolean }>()
|
||||||
|
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
if (props.clickable) {
|
if (props.clickable) {
|
||||||
router.push(`/profiles/${getSelectedProfile()}/categories`)
|
router.push(`/profiles/${getSelectedProfile(route)}/categories`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
import { TransactionApiClient, type TransactionCategoryTree } from '@/api/transaction';
|
import { TransactionApiClient, type TransactionCategoryTree } from '@/api/transaction';
|
||||||
import { onMounted, ref, type Ref } from 'vue';
|
import { onMounted, ref, type Ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const model = defineModel<number | null>({ required: true })
|
const model = defineModel<number | null>({ required: true })
|
||||||
defineProps<{ required?: boolean }>()
|
defineProps<{ required?: boolean }>()
|
||||||
defineEmits<{ categorySelected: [TransactionCategoryTree | null] }>()
|
defineEmits<{ categorySelected: [TransactionCategoryTree | null] }>()
|
||||||
const categories: Ref<TransactionCategoryTree[]> = ref([])
|
const categories: Ref<TransactionCategoryTree[]> = ref([])
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
api.getCategoriesFlattened()
|
api.getCategoriesFlattened()
|
||||||
.then(c => categories.value = c)
|
.then(c => categories.value = c)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ import FormGroup from './form/FormGroup.vue';
|
||||||
import FormControl from './form/FormControl.vue';
|
import FormControl from './form/FormControl.vue';
|
||||||
import AppButton from './AppButton.vue';
|
import AppButton from './AppButton.vue';
|
||||||
import CategorySelect from './CategorySelect.vue';
|
import CategorySelect from './CategorySelect.vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
category?: TransactionCategory
|
category?: TransactionCategory
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -52,7 +55,7 @@ function canSave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doSave() {
|
async function doSave() {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
const payload = {
|
const payload = {
|
||||||
name: name.value.trim(),
|
name: name.value.trim(),
|
||||||
description: description.value.trim(),
|
description: description.value.trim(),
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ import FormGroup from './form/FormGroup.vue';
|
||||||
import ModalWrapper from './ModalWrapper.vue';
|
import ModalWrapper from './ModalWrapper.vue';
|
||||||
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
|
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
|
||||||
import AppButton from './AppButton.vue';
|
import AppButton from './AppButton.vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
vendor?: TransactionVendor
|
vendor?: TransactionVendor
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -35,7 +38,7 @@ function canSave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doSave() {
|
async function doSave() {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
const payload = {
|
const payload = {
|
||||||
name: name.value.trim(),
|
name: name.value.trim(),
|
||||||
description: description.value.trim()
|
description: description.value.trim()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Page, PageRequest } from '@/api/pagination';
|
import type { Page, PageRequest } from '@/api/pagination';
|
||||||
|
import AppButton from './AppButton.vue';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps<{ page?: Page<unknown> }>()
|
const props = defineProps<{ page?: Page<unknown> }>()
|
||||||
|
|
@ -27,22 +28,24 @@ function incrementPage(step: number) {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<button :disabled="!page || page.isFirst" @click="updatePage(1)">
|
<div v-if="page && page.totalElements > 0">
|
||||||
First Page
|
<AppButton size="sm" :disabled="!page || page.isFirst" @click="updatePage(1)">
|
||||||
</button>
|
First Page
|
||||||
|
</AppButton>
|
||||||
|
|
||||||
<button :disabled="!page || page.isFirst" @click="incrementPage(-1)">
|
<AppButton size="sm" :disabled="!page || page.isFirst" @click="incrementPage(-1)">
|
||||||
Previous Page
|
Previous Page
|
||||||
</button>
|
</AppButton>
|
||||||
|
|
||||||
<span>Page {{ page?.pageRequest.page }} / {{ page?.totalPages }}</span>
|
<span>Page {{ page?.pageRequest.page }} / {{ page?.totalPages }}</span>
|
||||||
|
|
||||||
<button :disabled="!page || page.isLast" @click="incrementPage(1)">
|
<AppButton size="sm" :disabled="!page || page.isLast" @click="incrementPage(1)">
|
||||||
Next Page
|
Next Page
|
||||||
</button>
|
</AppButton>
|
||||||
|
|
||||||
<button :disabled="!page || page.isLast" @click="updatePage(page?.totalPages ?? 0)">
|
<AppButton size="sm" :disabled="!page || page.isLast" @click="updatePage(page?.totalPages ?? 0)">
|
||||||
Last Page
|
Last Page
|
||||||
</button>
|
</AppButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,15 @@ import type { PageRequest } from '@/api/pagination';
|
||||||
import { onMounted, ref, type Ref } from 'vue';
|
import { onMounted, ref, type Ref } from 'vue';
|
||||||
import ValueRecordHistoryItem from './ValueRecordHistoryItem.vue';
|
import ValueRecordHistoryItem from './ValueRecordHistoryItem.vue';
|
||||||
import JournalEntryHistoryItem from './JournalEntryHistoryItem.vue';
|
import JournalEntryHistoryItem from './JournalEntryHistoryItem.vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const props = defineProps<{ accountId: number }>()
|
const props = defineProps<{ accountId: number }>()
|
||||||
const historyItems: Ref<AccountHistoryItem[]> = ref([])
|
const historyItems: Ref<AccountHistoryItem[]> = ref([])
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const pageRequest: PageRequest = { page: 1, size: 10, sorts: [{ attribute: 'timestamp', dir: 'DESC' }] }
|
const pageRequest: PageRequest = { page: 1, size: 10, sorts: [{ attribute: 'timestamp', dir: 'DESC' }] }
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
const page = await api.getHistory(props.accountId, pageRequest)
|
const page = await api.getHistory(props.accountId, pageRequest)
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@
|
||||||
import type { AccountHistoryJournalEntryItem } from '@/api/account'
|
import type { AccountHistoryJournalEntryItem } from '@/api/account'
|
||||||
import { formatMoney } from '@/api/data';
|
import { formatMoney } from '@/api/data';
|
||||||
import { getSelectedProfile } from '@/api/profile';
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
defineProps<{ item: AccountHistoryJournalEntryItem }>()
|
defineProps<{ item: AccountHistoryJournalEntryItem }>()
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="history-item-content">
|
<div class="history-item-content">
|
||||||
<div>
|
<div>
|
||||||
<RouterLink :to="`/profiles/${getSelectedProfile()}/transactions/${item.transactionId}`">
|
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/transactions/${item.transactionId}`">
|
||||||
Transaction #{{ item.transactionId }}
|
Transaction #{{ item.transactionId }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
entered as a
|
entered as a
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@ import { AccountApiClient, type AccountHistoryValueRecordItem } from '@/api/acco
|
||||||
import { formatMoney } from '@/api/data';
|
import { formatMoney } from '@/api/data';
|
||||||
import AppButton from '../AppButton.vue';
|
import AppButton from '../AppButton.vue';
|
||||||
import { showConfirm } from '@/util/alert';
|
import { showConfirm } from '@/util/alert';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const props = defineProps<{ item: AccountHistoryValueRecordItem, accountId: number }>()
|
const props = defineProps<{ item: AccountHistoryValueRecordItem, accountId: number }>()
|
||||||
|
|
||||||
async function deleteValueRecord(id: number) {
|
async function deleteValueRecord(id: number) {
|
||||||
const confirm = await showConfirm('Are you sure you want to delete this value record?')
|
const confirm = await showConfirm('Are you sure you want to delete this value record?')
|
||||||
if (!confirm) return
|
if (!confirm) return
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
try {
|
try {
|
||||||
await api.deleteValueRecord(props.accountId, id)
|
await api.deleteValueRecord(props.accountId, id)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const account: Ref<Account | null> = ref(null)
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const accountId = parseInt(route.params.id as string)
|
const accountId = parseInt(route.params.id as string)
|
||||||
try {
|
try {
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
account.value = await api.getAccount(accountId)
|
account.value = await api.getAccount(accountId)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
@ -32,9 +32,9 @@ async function deleteAccount() {
|
||||||
if (!account.value) return
|
if (!account.value) return
|
||||||
if (await showConfirm('Are you sure you want to delete this account? This will permanently remove the account and all associated transactions.')) {
|
if (await showConfirm('Are you sure you want to delete this account? This will permanently remove the account and all associated transactions.')) {
|
||||||
try {
|
try {
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
await api.deleteAccount(account.value.id)
|
await api.deleteAccount(account.value.id)
|
||||||
await router.replace(`/profiles/${getSelectedProfile()}`)
|
await router.replace(`/profiles/${getSelectedProfile(route)}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,8 @@ async function addValueRecord() {
|
||||||
</PropertiesTable>
|
</PropertiesTable>
|
||||||
<div>
|
<div>
|
||||||
<AppButton @click="addValueRecord()">Record Value</AppButton>
|
<AppButton @click="addValueRecord()">Record Value</AppButton>
|
||||||
<AppButton icon="wrench" @click="router.push(`/profiles/${getSelectedProfile()}/accounts/${account?.id}/edit`)">
|
<AppButton icon="wrench"
|
||||||
|
@click="router.push(`/profiles/${getSelectedProfile(route)}/accounts/${account?.id}/edit`)">
|
||||||
Edit</AppButton>
|
Edit</AppButton>
|
||||||
<AppButton icon="trash" @click="deleteAccount()">Delete</AppButton>
|
<AppButton icon="trash" @click="deleteAccount()">Delete</AppButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
import { TransactionApiClient, type TransactionCategory, type TransactionCategoryTree } from '@/api/transaction';
|
import { TransactionApiClient, type TransactionCategory, type TransactionCategoryTree } from '@/api/transaction';
|
||||||
import AppButton from '@/components/AppButton.vue';
|
import AppButton from '@/components/AppButton.vue';
|
||||||
import AppPage from '@/components/AppPage.vue';
|
import AppPage from '@/components/AppPage.vue';
|
||||||
|
|
@ -7,6 +8,9 @@ import EditCategoryModal from '@/components/EditCategoryModal.vue';
|
||||||
import { showConfirm } from '@/util/alert';
|
import { showConfirm } from '@/util/alert';
|
||||||
import { hideLoader, showLoader } from '@/util/loader';
|
import { hideLoader, showLoader } from '@/util/loader';
|
||||||
import { nextTick, onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
import { nextTick, onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const editCategoryModal = useTemplateRef('editCategoryModal')
|
const editCategoryModal = useTemplateRef('editCategoryModal')
|
||||||
|
|
||||||
|
|
@ -18,13 +22,13 @@ onMounted(async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function loadCategories() {
|
async function loadCategories() {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
categories.value = await api.getCategories()
|
categories.value = await api.getCategories()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editCategory(categoryId: number) {
|
async function editCategory(categoryId: number) {
|
||||||
try {
|
try {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
editedCategory.value = await api.getCategory(categoryId)
|
editedCategory.value = await api.getCategory(categoryId)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
const result = await editCategoryModal.value?.show()
|
const result = await editCategoryModal.value?.show()
|
||||||
|
|
@ -41,7 +45,7 @@ async function deleteCategory(categoryId: number) {
|
||||||
if (result) {
|
if (result) {
|
||||||
try {
|
try {
|
||||||
showLoader()
|
showLoader()
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
await api.deleteCategory(categoryId)
|
await api.deleteCategory(categoryId)
|
||||||
await loadCategories()
|
await loadCategories()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ function generateSampleData() {
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<div style="display: flex; margin-left: 1rem; margin-right: 1rem;">
|
<div style="display: flex; margin-left: 1rem; margin-right: 1rem;">
|
||||||
<AppButton button-type="submit" :disabled="disableForm || !isDataValid()" style="flex-grow: 1;">Login
|
<AppButton type="submit" :disabled="disableForm || !isDataValid()" style="flex-grow: 1;">Login
|
||||||
</AppButton>
|
</AppButton>
|
||||||
<AppButton button-type="button" button-style="secondary" :disabled="disableForm || !isDataValid()"
|
<AppButton button-type="button" button-style="secondary" :disabled="disableForm || !isDataValid()"
|
||||||
@click="doRegister()">Register</AppButton>
|
@click="doRegister()">Register</AppButton>
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ async function doChangePassword() {
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:buttons>
|
<template v-slot:buttons>
|
||||||
<AppButton @click="doChangePassword()">Change</AppButton>
|
<AppButton @click="doChangePassword()">Change</AppButton>
|
||||||
<AppButton button-style="secondary" @click="changePasswordModal?.close()">Cancel</AppButton>
|
<AppButton theme="secondary" @click="changePasswordModal?.close()">Cancel</AppButton>
|
||||||
</template>
|
</template>
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
</AppPage>
|
</AppPage>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
accounts.value = await api.getAccounts()
|
accounts.value = await api.getAccounts()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load accounts', err)
|
console.error('Failed to load accounts', err)
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@ function selectProfile(profile: Profile) {
|
||||||
async function addProfile() {
|
async function addProfile() {
|
||||||
try {
|
try {
|
||||||
const api = new ProfileApiClient()
|
const api = new ProfileApiClient()
|
||||||
api.createProfile(newProfileName.value)
|
const newProfile = await api.createProfile(newProfileName.value)
|
||||||
newProfileName.value = ''
|
newProfileName.value = ''
|
||||||
addProfileModal.value?.close()
|
addProfileModal.value?.close()
|
||||||
await fetchProfiles()
|
await router.push('/profiles/' + newProfile.name)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
|
|
@ -45,8 +45,8 @@ async function addProfile() {
|
||||||
<div class="profile-card" v-for="profile in profiles" :key="profile.name" @click="selectProfile(profile)">
|
<div class="profile-card" v-for="profile in profiles" :key="profile.name" @click="selectProfile(profile)">
|
||||||
<span>{{ profile.name }}</span>
|
<span>{{ profile.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile-card" @click="addProfileModal?.show()">
|
<div style="text-align: right;">
|
||||||
<span>Add a new profile...</span>
|
<AppButton icon="plus" @click="addProfileModal?.show()">Add a new profile</AppButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ModalWrapper ref="addProfileModal">
|
<ModalWrapper ref="addProfileModal">
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const transactionApi = new TransactionApiClient(getSelectedProfile(route))
|
||||||
|
|
||||||
const transaction: Ref<TransactionDetail | undefined> = ref()
|
const transaction: Ref<TransactionDetail | undefined> = ref()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const transactionId = parseInt(route.params.id as string)
|
const transactionId = parseInt(route.params.id as string)
|
||||||
try {
|
try {
|
||||||
const api = new TransactionApiClient()
|
transaction.value = await transactionApi.getTransaction(transactionId)
|
||||||
transaction.value = await api.getTransaction(transactionId)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
await router.replace('/')
|
await router.replace('/')
|
||||||
|
|
@ -36,8 +36,8 @@ async function deleteTransaction() {
|
||||||
const conf = await showConfirm('Are you sure you want to delete this transaction? This will permanently delete all data pertaining to this transaction, and it cannot be recovered.')
|
const conf = await showConfirm('Are you sure you want to delete this transaction? This will permanently delete all data pertaining to this transaction, and it cannot be recovered.')
|
||||||
if (!conf) return
|
if (!conf) return
|
||||||
try {
|
try {
|
||||||
await new TransactionApiClient().deleteTransaction(transaction.value.id)
|
await transactionApi.deleteTransaction(transaction.value.id)
|
||||||
await router.replace(`/profiles/${getSelectedProfile()}`)
|
await router.replace(`/profiles/${getSelectedProfile(route)}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ async function deleteTransaction() {
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<AppButton icon="wrench"
|
<AppButton icon="wrench"
|
||||||
@click="router.push(`/profiles/${getSelectedProfile()}/transactions/${transaction.id}/edit`)">
|
@click="router.push(`/profiles/${getSelectedProfile(route)}/transactions/${transaction.id}/edit`)">
|
||||||
Edit
|
Edit
|
||||||
</AppButton>
|
</AppButton>
|
||||||
<AppButton icon="trash" @click="deleteTransaction()">Delete</AppButton>
|
<AppButton icon="trash" @click="deleteTransaction()">Delete</AppButton>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getSelectedProfile } from '@/api/profile';
|
||||||
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
|
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
|
||||||
import AppButton from '@/components/AppButton.vue';
|
import AppButton from '@/components/AppButton.vue';
|
||||||
import AppPage from '@/components/AppPage.vue';
|
import AppPage from '@/components/AppPage.vue';
|
||||||
import EditVendorModal from '@/components/EditVendorModal.vue';
|
import EditVendorModal from '@/components/EditVendorModal.vue';
|
||||||
import { showConfirm } from '@/util/alert';
|
import { showConfirm } from '@/util/alert';
|
||||||
import { onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
import { onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const transactionApi = new TransactionApiClient(getSelectedProfile(route))
|
||||||
|
|
||||||
const vendors: Ref<TransactionVendor[]> = ref([])
|
const vendors: Ref<TransactionVendor[]> = ref([])
|
||||||
const editVendorModal = useTemplateRef('editVendorModal')
|
const editVendorModal = useTemplateRef('editVendorModal')
|
||||||
|
|
@ -15,8 +20,7 @@ onMounted(async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function loadVendors() {
|
async function loadVendors() {
|
||||||
const api = new TransactionApiClient()
|
vendors.value = await transactionApi.getVendors()
|
||||||
vendors.value = await api.getVendors()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addVendor() {
|
async function addVendor() {
|
||||||
|
|
@ -38,8 +42,7 @@ async function editVendor(vendor: TransactionVendor) {
|
||||||
async function deleteVendor(vendor: TransactionVendor) {
|
async function deleteVendor(vendor: TransactionVendor) {
|
||||||
const confirmed = await showConfirm('Are you sure you want to delete this vendor? It will be permanently removed from all associated transactions.')
|
const confirmed = await showConfirm('Are you sure you want to delete this vendor? It will be permanently removed from all associated transactions.')
|
||||||
if (!confirmed) return
|
if (!confirmed) return
|
||||||
const api = new TransactionApiClient()
|
await transactionApi.deleteVendor(vendor.id)
|
||||||
await api.deleteVendor(vendor.id)
|
|
||||||
await loadVendors()
|
await loadVendors()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ onMounted(async () => {
|
||||||
const accountId = parseInt(accountIdStr)
|
const accountId = parseInt(accountIdStr)
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
existingAccount.value = await api.getAccount(accountId)
|
existingAccount.value = await api.getAccount(accountId)
|
||||||
accountName.value = existingAccount.value.name
|
accountName.value = existingAccount.value.name
|
||||||
accountType.value = AccountTypes.of(existingAccount.value.type)
|
accountType.value = AccountTypes.of(existingAccount.value.type)
|
||||||
|
|
@ -55,12 +55,12 @@ async function doSubmit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const api = new AccountApiClient()
|
const api = new AccountApiClient(route)
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const account = editing.value
|
const account = editing.value
|
||||||
? await api.updateAccount(existingAccount.value?.id ?? 0, payload)
|
? await api.updateAccount(existingAccount.value?.id ?? 0, payload)
|
||||||
: await api.createAccount(payload)
|
: await api.createAccount(payload)
|
||||||
await router.replace(`/profiles/${getSelectedProfile()}/accounts/${account.id}`)
|
await router.replace(`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -101,7 +101,7 @@ async function doSubmit() {
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormActions @cancel="router.replace(`/profiles/${getSelectedProfile()}`)" :disabled="loading"
|
<FormActions @cancel="router.replace(`/profiles/${getSelectedProfile(route)}`)" :disabled="loading"
|
||||||
:submit-text="editing ? 'Save' : 'Add'" />
|
:submit-text="editing ? 'Save' : 'Add'" />
|
||||||
</AppForm>
|
</AppForm>
|
||||||
</AppPage>
|
</AppPage>
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ import { useRoute, useRouter, } from 'vue-router';
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const transactionApi = new TransactionApiClient(getSelectedProfile(route))
|
||||||
|
const accountApi = new AccountApiClient(route)
|
||||||
|
|
||||||
const existingTransaction: Ref<TransactionDetail | null> = ref(null)
|
const existingTransaction: Ref<TransactionDetail | null> = ref(null)
|
||||||
const editing = computed(() => {
|
const editing = computed(() => {
|
||||||
return existingTransaction.value !== null || route.meta.title === 'Edit Transaction'
|
return existingTransaction.value !== null || route.meta.title === 'Edit Transaction'
|
||||||
|
|
@ -80,14 +83,12 @@ watch(availableCurrencies, (newValue: Currency[]) => {
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const dataClient = new DataApiClient()
|
const dataClient = new DataApiClient()
|
||||||
const transactionClient = new TransactionApiClient()
|
|
||||||
const accountClient = new AccountApiClient()
|
|
||||||
|
|
||||||
// Fetch various collections of data needed for different user choices.
|
// Fetch various collections of data needed for different user choices.
|
||||||
dataClient.getCurrencies().then(currencies => allCurrencies.value = currencies)
|
dataClient.getCurrencies().then(currencies => allCurrencies.value = currencies)
|
||||||
transactionClient.getVendors().then(vendors => availableVendors.value = vendors)
|
transactionApi.getVendors().then(vendors => availableVendors.value = vendors)
|
||||||
transactionClient.getAllTags().then(t => allTags.value = t)
|
transactionApi.getAllTags().then(t => allTags.value = t)
|
||||||
accountClient.getAccounts().then(accounts => allAccounts.value = accounts)
|
accountApi.getAccounts().then(accounts => allAccounts.value = accounts)
|
||||||
|
|
||||||
|
|
||||||
const transactionIdStr = route.params.id
|
const transactionIdStr = route.params.id
|
||||||
|
|
@ -95,7 +96,7 @@ onMounted(async () => {
|
||||||
const transactionId = parseInt(transactionIdStr)
|
const transactionId = parseInt(transactionIdStr)
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
existingTransaction.value = await transactionClient.getTransaction(transactionId)
|
existingTransaction.value = await transactionApi.getTransaction(transactionId)
|
||||||
loadValuesFromExistingTransaction(existingTransaction.value)
|
loadValuesFromExistingTransaction(existingTransaction.value)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
@ -133,7 +134,6 @@ async function doSubmit() {
|
||||||
attachmentIdsToRemove: removedAttachmentIds.value
|
attachmentIdsToRemove: removedAttachmentIds.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const transactionApi = new TransactionApiClient()
|
|
||||||
let savedTransaction = null
|
let savedTransaction = null
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
@ -142,7 +142,7 @@ async function doSubmit() {
|
||||||
} else {
|
} else {
|
||||||
savedTransaction = await transactionApi.addTransaction(payload, attachmentsToUpload.value)
|
savedTransaction = await transactionApi.addTransaction(payload, attachmentsToUpload.value)
|
||||||
}
|
}
|
||||||
await router.replace(`/profiles/${getSelectedProfile()}/transactions/${savedTransaction.id}`)
|
await router.replace(`/profiles/${getSelectedProfile(route)}/transactions/${savedTransaction.id}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -156,9 +156,9 @@ async function doSubmit() {
|
||||||
*/
|
*/
|
||||||
function doCancel() {
|
function doCancel() {
|
||||||
if (editing.value) {
|
if (editing.value) {
|
||||||
router.replace(`/profiles/${getSelectedProfile()}/transactions/${existingTransaction.value?.id}`)
|
router.replace(`/profiles/${getSelectedProfile(route)}/transactions/${existingTransaction.value?.id}`)
|
||||||
} else {
|
} else {
|
||||||
router.replace(`/profiles/${getSelectedProfile()}`)
|
router.replace(`/profiles/${getSelectedProfile(route)}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,15 @@ import { getSelectedProfile } from '@/api/profile'
|
||||||
import AppButton from '@/components/AppButton.vue'
|
import AppButton from '@/components/AppButton.vue'
|
||||||
import HomeModule from '@/components/HomeModule.vue'
|
import HomeModule from '@/components/HomeModule.vue'
|
||||||
import { onMounted, ref, type Ref } from 'vue'
|
import { onMounted, ref, type Ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const accounts: Ref<Account[]> = ref([])
|
const accounts: Ref<Account[]> = ref([])
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const accountApi = new AccountApiClient()
|
const accountApi = new AccountApiClient(route)
|
||||||
accountApi.getAccounts().then(result => accounts.value = result)
|
accountApi.getAccounts().then(result => accounts.value = result)
|
||||||
.catch(err => console.error(err))
|
.catch(err => console.error(err))
|
||||||
})
|
})
|
||||||
|
|
@ -33,7 +34,7 @@ onMounted(async () => {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="account in accounts" :key="account.id">
|
<tr v-for="account in accounts" :key="account.id">
|
||||||
<td>
|
<td>
|
||||||
<RouterLink :to="`/profiles/${getSelectedProfile()}/accounts/${account.id}`">{{ account.name }}
|
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`">{{ account.name }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ account.currency.code }}</td>
|
<td>{{ account.currency.code }}</td>
|
||||||
|
|
@ -48,7 +49,7 @@ onMounted(async () => {
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
<AppButton icon="plus" @click="router.push(`/profiles/${getSelectedProfile()}/add-account`)">Add Account
|
<AppButton icon="plus" @click="router.push(`/profiles/${getSelectedProfile(route)}/add-account`)">Add Account
|
||||||
</AppButton>
|
</AppButton>
|
||||||
</template>
|
</template>
|
||||||
</HomeModule>
|
</HomeModule>
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,17 @@ import ConfirmModal from '@/components/ConfirmModal.vue';
|
||||||
import HomeModule from '@/components/HomeModule.vue';
|
import HomeModule from '@/components/HomeModule.vue';
|
||||||
import { showAlert } from '@/util/alert';
|
import { showAlert } from '@/util/alert';
|
||||||
import { onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
import { onMounted, ref, useTemplateRef, type Ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const confirmDeleteModal = useTemplateRef('confirmDeleteModal')
|
const confirmDeleteModal = useTemplateRef('confirmDeleteModal')
|
||||||
|
|
||||||
const profile: Ref<Profile | undefined> = ref()
|
const profile: Ref<Profile | undefined> = ref()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
profile.value = await new ProfileApiClient().getProfile(getSelectedProfile())
|
profile.value = await new ProfileApiClient().getProfile(getSelectedProfile(route))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
await showAlert("Failed to get profile.")
|
await showAlert("Failed to get profile.")
|
||||||
|
|
@ -23,7 +24,7 @@ onMounted(async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function deleteProfile() {
|
async function deleteProfile() {
|
||||||
const currentProfileName = getSelectedProfile()
|
const currentProfileName = getSelectedProfile(route)
|
||||||
if (await confirmDeleteModal.value?.confirm()) {
|
if (await confirmDeleteModal.value?.confirm()) {
|
||||||
const api = new ProfileApiClient()
|
const api = new ProfileApiClient()
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ import AppButton from '@/components/AppButton.vue';
|
||||||
import HomeModule from '@/components/HomeModule.vue';
|
import HomeModule from '@/components/HomeModule.vue';
|
||||||
import PaginationControls from '@/components/PaginationControls.vue';
|
import PaginationControls from '@/components/PaginationControls.vue';
|
||||||
import { onMounted, ref, type Ref } from 'vue';
|
import { onMounted, ref, type Ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const transactions: Ref<Page<TransactionsListItem>> = ref({ items: [], pageRequest: { page: 1, size: 10, sorts: [] }, totalElements: 0, totalPages: 0, isFirst: true, isLast: true })
|
const transactions: Ref<Page<TransactionsListItem>> = ref({ items: [], pageRequest: { page: 1, size: 10, sorts: [] }, totalElements: 0, totalPages: 0, isFirst: true, isLast: true })
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|
@ -17,7 +18,7 @@ onMounted(async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function fetchPage(pageRequest: PageRequest) {
|
async function fetchPage(pageRequest: PageRequest) {
|
||||||
const api = new TransactionApiClient()
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
||||||
try {
|
try {
|
||||||
transactions.value = await api.getTransactions(pageRequest)
|
transactions.value = await api.getTransactions(pageRequest)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -50,18 +51,18 @@ async function fetchPage(pageRequest: PageRequest) {
|
||||||
<td>{{ tx.description }}</td>
|
<td>{{ tx.description }}</td>
|
||||||
<td>
|
<td>
|
||||||
<RouterLink v-if="tx.creditedAccount"
|
<RouterLink v-if="tx.creditedAccount"
|
||||||
:to="`/profiles/${getSelectedProfile()}/accounts/${tx.creditedAccount.id}`">
|
:to="`/profiles/${getSelectedProfile(route)}/accounts/${tx.creditedAccount.id}`">
|
||||||
{{ tx.creditedAccount?.name }}
|
{{ tx.creditedAccount?.name }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<RouterLink v-if="tx.debitedAccount"
|
<RouterLink v-if="tx.debitedAccount"
|
||||||
:to="`/profiles/${getSelectedProfile()}/accounts/${tx.debitedAccount.id}`">
|
:to="`/profiles/${getSelectedProfile(route)}/accounts/${tx.debitedAccount.id}`">
|
||||||
{{ tx.debitedAccount?.name }}
|
{{ tx.debitedAccount?.name }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<RouterLink :to="`/profiles/${getSelectedProfile()}/transactions/${tx.id}`">View</RouterLink>
|
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/transactions/${tx.id}`">View</RouterLink>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -69,7 +70,8 @@ async function fetchPage(pageRequest: PageRequest) {
|
||||||
<PaginationControls :page="transactions" @update="pr => fetchPage(pr)"></PaginationControls>
|
<PaginationControls :page="transactions" @update="pr => fetchPage(pr)"></PaginationControls>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
<AppButton icon="plus" @click="router.push(`/profiles/${getSelectedProfile()}/add-transaction`)">Add
|
<AppButton size="sm" icon="plus" @click="router.push(`/profiles/${getSelectedProfile(route)}/add-transaction`)">
|
||||||
|
Add
|
||||||
Transaction</AppButton>
|
Transaction</AppButton>
|
||||||
</template>
|
</template>
|
||||||
</HomeModule>
|
</HomeModule>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue