Clean up profile handling again!

This commit is contained in:
andrewlalis 2025-08-31 16:43:37 -04:00
parent a674421337
commit 074b4ded1d
26 changed files with 152 additions and 96 deletions

View File

@ -1,3 +1,4 @@
import { type RouteLocation } from 'vue-router'
import { ApiClient } from './base'
import type { Currency } from './data'
import type { Page, PageRequest } from './pagination'
@ -125,9 +126,9 @@ export interface AccountHistoryJournalEntryItem extends AccountHistoryItem {
export class AccountApiClient extends ApiClient {
readonly path: string
constructor() {
constructor(route: RouteLocation) {
super()
this.path = `/profiles/${getSelectedProfile()}/accounts`
this.path = `/profiles/${getSelectedProfile(route)}/accounts`
}
getAccounts(): Promise<Account[]> {

View File

@ -1,4 +1,4 @@
import { useRoute, type RouteLocation } from 'vue-router'
import { type RouteLocation } from 'vue-router'
import { ApiClient } from './base'
export interface Profile {
@ -35,11 +35,10 @@ export class ProfileApiClient extends ApiClient {
/**
* Gets the currently selected profile. Throws an error in any case where
* the route doesn't contain profile name information.
* @param route The route to get the profile from. Defaults to getting it from
* Vue's `useRoute()` which is available in component contexts.
* @param route The route to get the profile from.
* @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)) {
throw new Error('No "profileName" route property available.')
}

View File

@ -1,7 +1,6 @@
import { ApiClient } from './base'
import type { Currency } from './data'
import { type Page, type PageRequest } from './pagination'
import { getSelectedProfile } from './profile'
export interface TransactionVendor {
id: number
@ -144,9 +143,9 @@ export interface CreateCategoryPayload {
export class TransactionApiClient extends ApiClient {
readonly path: string
constructor() {
constructor(profileName: string) {
super()
this.path = `/profiles/${getSelectedProfile()}`
this.path = `/profiles/${profileName}`
}
getVendors(): Promise<TransactionVendor[]> {

View File

@ -8,7 +8,9 @@ import AppButton from './AppButton.vue';
import { AccountApiClient, AccountValueRecordType, type Account, type AccountValueRecord, type AccountValueRecordCreationPayload } from '@/api/account';
import { datetimeLocalToISO, getDatetimeLocalValueForNow } from '@/util/time';
import FileSelector from './FileSelector.vue';
import { useRoute } from 'vue-router';
const route = useRoute()
const props = defineProps<{ account: Account }>()
const modal = useTemplateRef('modal')
const savedValueRecord: Ref<AccountValueRecord | undefined> = ref(undefined)
@ -36,7 +38,7 @@ async function addValueRecord() {
type: AccountValueRecordType.BALANCE,
value: amount.value
}
const api = new AccountApiClient()
const api = new AccountApiClient(route)
try {
savedValueRecord.value = await api.createValueRecord(props.account.id, payload, attachments.value)
modal.value?.close('saved')

View File

@ -1,17 +1,35 @@
<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,
buttonType?: "button" | "submit" | "reset" | undefined,
type?: ButtonType,
disabled?: boolean
}>()
}
const props = withDefaults(defineProps<Props>(), {
buttonStyle: "primary",
buttonType: "button",
size: "md",
disabled: false
})
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>
<template>
<button class="app-button"
:class="{ 'app-button-secondary': buttonStyle === 'secondary', 'app-button-disabled': disabled ?? false }"
@click="$emit('click')" :type="buttonType" :disabled="disabled ?? false">
<button class="app-button" :class="buttonStyle" :type="type" :disabled="disabled" @click="$emit('click')">
<span v-if="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>
@ -51,6 +69,17 @@ defineEmits(['click'])
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) {
background-color: #374151;
}
@ -65,13 +94,7 @@ defineEmits(['click'])
background-color: #3b4968;
}
@media (min-width: 768px) {
.app-button {
padding: .75rem 1.5rem;
}
}
.app-button-secondary {
.app-button-theme-secondary {
background-color: #1d2330;
}

View File

@ -1,14 +1,15 @@
<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile';
import type { TransactionCategory } from '@/api/transaction';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute()
const router = useRouter()
const props = defineProps<{ category: TransactionCategory, clickable?: boolean }>()
function onClicked() {
if (props.clickable) {
router.push(`/profiles/${getSelectedProfile()}/categories`)
router.push(`/profiles/${getSelectedProfile(route)}/categories`)
}
}
</script>

View File

@ -1,15 +1,17 @@
<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile';
import { TransactionApiClient, type TransactionCategoryTree } from '@/api/transaction';
import { onMounted, ref, type Ref } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute()
const model = defineModel<number | null>({ required: true })
defineProps<{ required?: boolean }>()
defineEmits<{ categorySelected: [TransactionCategoryTree | null] }>()
const categories: Ref<TransactionCategoryTree[]> = ref([])
onMounted(() => {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
api.getCategoriesFlattened()
.then(c => categories.value = c)
})

View File

@ -7,7 +7,10 @@ import FormGroup from './form/FormGroup.vue';
import FormControl from './form/FormControl.vue';
import AppButton from './AppButton.vue';
import CategorySelect from './CategorySelect.vue';
import { useRoute } from 'vue-router';
import { getSelectedProfile } from '@/api/profile';
const route = useRoute()
const props = defineProps<{
category?: TransactionCategory
}>()
@ -52,7 +55,7 @@ function canSave() {
}
async function doSave() {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
const payload = {
name: name.value.trim(),
description: description.value.trim(),

View File

@ -6,7 +6,10 @@ import FormGroup from './form/FormGroup.vue';
import ModalWrapper from './ModalWrapper.vue';
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
import AppButton from './AppButton.vue';
import { useRoute } from 'vue-router';
import { getSelectedProfile } from '@/api/profile';
const route = useRoute()
const props = defineProps<{
vendor?: TransactionVendor
}>()
@ -35,7 +38,7 @@ function canSave() {
}
async function doSave() {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
const payload = {
name: name.value.trim(),
description: description.value.trim()

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import type { Page, PageRequest } from '@/api/pagination';
import AppButton from './AppButton.vue';
const props = defineProps<{ page?: Page<unknown> }>()
@ -27,22 +28,24 @@ function incrementPage(step: number) {
</script>
<template>
<div>
<button :disabled="!page || page.isFirst" @click="updatePage(1)">
First Page
</button>
<div v-if="page && page.totalElements > 0">
<AppButton size="sm" :disabled="!page || page.isFirst" @click="updatePage(1)">
First Page
</AppButton>
<button :disabled="!page || page.isFirst" @click="incrementPage(-1)">
Previous Page
</button>
<AppButton size="sm" :disabled="!page || page.isFirst" @click="incrementPage(-1)">
Previous Page
</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)">
Next Page
</button>
<AppButton size="sm" :disabled="!page || page.isLast" @click="incrementPage(1)">
Next Page
</AppButton>
<button :disabled="!page || page.isLast" @click="updatePage(page?.totalPages ?? 0)">
Last Page
</button>
<AppButton size="sm" :disabled="!page || page.isLast" @click="updatePage(page?.totalPages ?? 0)">
Last Page
</AppButton>
</div>
</div>
</template>

View File

@ -4,13 +4,15 @@ import type { PageRequest } from '@/api/pagination';
import { onMounted, ref, type Ref } from 'vue';
import ValueRecordHistoryItem from './ValueRecordHistoryItem.vue';
import JournalEntryHistoryItem from './JournalEntryHistoryItem.vue';
import { useRoute } from 'vue-router';
const route = useRoute()
const props = defineProps<{ accountId: number }>()
const historyItems: Ref<AccountHistoryItem[]> = ref([])
onMounted(async () => {
const pageRequest: PageRequest = { page: 1, size: 10, sorts: [{ attribute: 'timestamp', dir: 'DESC' }] }
const api = new AccountApiClient()
const api = new AccountApiClient(route)
while (true) {
try {
const page = await api.getHistory(props.accountId, pageRequest)

View File

@ -2,13 +2,16 @@
import type { AccountHistoryJournalEntryItem } from '@/api/account'
import { formatMoney } from '@/api/data';
import { getSelectedProfile } from '@/api/profile';
import { useRoute } from 'vue-router';
const route = useRoute()
defineProps<{ item: AccountHistoryJournalEntryItem }>()
</script>
<template>
<div class="history-item-content">
<div>
<RouterLink :to="`/profiles/${getSelectedProfile()}/transactions/${item.transactionId}`">
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/transactions/${item.transactionId}`">
Transaction #{{ item.transactionId }}
</RouterLink>
entered as a

View File

@ -3,13 +3,16 @@ import { AccountApiClient, type AccountHistoryValueRecordItem } from '@/api/acco
import { formatMoney } from '@/api/data';
import AppButton from '../AppButton.vue';
import { showConfirm } from '@/util/alert';
import { useRoute } from 'vue-router';
const route = useRoute()
const props = defineProps<{ item: AccountHistoryValueRecordItem, accountId: number }>()
async function deleteValueRecord(id: number) {
const confirm = await showConfirm('Are you sure you want to delete this value record?')
if (!confirm) return
const api = new AccountApiClient()
const api = new AccountApiClient(route)
try {
await api.deleteValueRecord(props.accountId, id)
} catch (err) {

View File

@ -20,7 +20,7 @@ const account: Ref<Account | null> = ref(null)
onMounted(async () => {
const accountId = parseInt(route.params.id as string)
try {
const api = new AccountApiClient()
const api = new AccountApiClient(route)
account.value = await api.getAccount(accountId)
} catch (err) {
console.error(err)
@ -32,9 +32,9 @@ async function deleteAccount() {
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.')) {
try {
const api = new AccountApiClient()
const api = new AccountApiClient(route)
await api.deleteAccount(account.value.id)
await router.replace(`/profiles/${getSelectedProfile()}`)
await router.replace(`/profiles/${getSelectedProfile(route)}`)
} catch (err) {
console.error(err)
}
@ -90,7 +90,8 @@ async function addValueRecord() {
</PropertiesTable>
<div>
<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>
<AppButton icon="trash" @click="deleteAccount()">Delete</AppButton>
</div>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile';
import { TransactionApiClient, type TransactionCategory, type TransactionCategoryTree } from '@/api/transaction';
import AppButton from '@/components/AppButton.vue';
import AppPage from '@/components/AppPage.vue';
@ -7,6 +8,9 @@ import EditCategoryModal from '@/components/EditCategoryModal.vue';
import { showConfirm } from '@/util/alert';
import { hideLoader, showLoader } from '@/util/loader';
import { nextTick, onMounted, ref, useTemplateRef, type Ref } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute()
const editCategoryModal = useTemplateRef('editCategoryModal')
@ -18,13 +22,13 @@ onMounted(async () => {
})
async function loadCategories() {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
categories.value = await api.getCategories()
}
async function editCategory(categoryId: number) {
try {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
editedCategory.value = await api.getCategory(categoryId)
await nextTick()
const result = await editCategoryModal.value?.show()
@ -41,7 +45,7 @@ async function deleteCategory(categoryId: number) {
if (result) {
try {
showLoader()
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
await api.deleteCategory(categoryId)
await loadCategories()
} catch (err) {

View File

@ -86,7 +86,7 @@ function generateSampleData() {
</FormControl>
</FormGroup>
<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 button-type="button" button-style="secondary" :disabled="disableForm || !isDataValid()"
@click="doRegister()">Register</AppButton>

View File

@ -84,7 +84,7 @@ async function doChangePassword() {
</template>
<template v-slot:buttons>
<AppButton @click="doChangePassword()">Change</AppButton>
<AppButton button-style="secondary" @click="changePasswordModal?.close()">Cancel</AppButton>
<AppButton theme="secondary" @click="changePasswordModal?.close()">Cancel</AppButton>
</template>
</ModalWrapper>
</AppPage>

View File

@ -26,7 +26,7 @@ onMounted(async () => {
}
try {
const api = new AccountApiClient()
const api = new AccountApiClient(route)
accounts.value = await api.getAccounts()
} catch (err) {
console.error('Failed to load accounts', err)

View File

@ -31,10 +31,10 @@ function selectProfile(profile: Profile) {
async function addProfile() {
try {
const api = new ProfileApiClient()
api.createProfile(newProfileName.value)
const newProfile = await api.createProfile(newProfileName.value)
newProfileName.value = ''
addProfileModal.value?.close()
await fetchProfiles()
await router.push('/profiles/' + newProfile.name)
} catch (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)">
<span>{{ profile.name }}</span>
</div>
<div class="profile-card" @click="addProfileModal?.show()">
<span>Add a new profile...</span>
<div style="text-align: right;">
<AppButton icon="plus" @click="addProfileModal?.show()">Add a new profile</AppButton>
</div>
<ModalWrapper ref="addProfileModal">

View File

@ -14,14 +14,14 @@ import { useRoute, useRouter } from 'vue-router';
const route = useRoute()
const router = useRouter()
const transactionApi = new TransactionApiClient(getSelectedProfile(route))
const transaction: Ref<TransactionDetail | undefined> = ref()
onMounted(async () => {
const transactionId = parseInt(route.params.id as string)
try {
const api = new TransactionApiClient()
transaction.value = await api.getTransaction(transactionId)
transaction.value = await transactionApi.getTransaction(transactionId)
} catch (err) {
console.error(err)
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.')
if (!conf) return
try {
await new TransactionApiClient().deleteTransaction(transaction.value.id)
await router.replace(`/profiles/${getSelectedProfile()}`)
await transactionApi.deleteTransaction(transaction.value.id)
await router.replace(`/profiles/${getSelectedProfile(route)}`)
} catch (err) {
console.error(err)
}
@ -119,7 +119,7 @@ async function deleteTransaction() {
</div>
<div>
<AppButton icon="wrench"
@click="router.push(`/profiles/${getSelectedProfile()}/transactions/${transaction.id}/edit`)">
@click="router.push(`/profiles/${getSelectedProfile(route)}/transactions/${transaction.id}/edit`)">
Edit
</AppButton>
<AppButton icon="trash" @click="deleteTransaction()">Delete</AppButton>

View File

@ -1,10 +1,15 @@
<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile';
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction';
import AppButton from '@/components/AppButton.vue';
import AppPage from '@/components/AppPage.vue';
import EditVendorModal from '@/components/EditVendorModal.vue';
import { showConfirm } from '@/util/alert';
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 editVendorModal = useTemplateRef('editVendorModal')
@ -15,8 +20,7 @@ onMounted(async () => {
})
async function loadVendors() {
const api = new TransactionApiClient()
vendors.value = await api.getVendors()
vendors.value = await transactionApi.getVendors()
}
async function addVendor() {
@ -38,8 +42,7 @@ async function editVendor(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.')
if (!confirmed) return
const api = new TransactionApiClient()
await api.deleteVendor(vendor.id)
await transactionApi.deleteVendor(vendor.id)
await loadVendors()
}
</script>

View File

@ -30,7 +30,7 @@ onMounted(async () => {
const accountId = parseInt(accountIdStr)
try {
loading.value = true
const api = new AccountApiClient()
const api = new AccountApiClient(route)
existingAccount.value = await api.getAccount(accountId)
accountName.value = existingAccount.value.name
accountType.value = AccountTypes.of(existingAccount.value.type)
@ -55,12 +55,12 @@ async function doSubmit() {
}
try {
const api = new AccountApiClient()
const api = new AccountApiClient(route)
loading.value = true
const account = editing.value
? await api.updateAccount(existingAccount.value?.id ?? 0, payload)
: await api.createAccount(payload)
await router.replace(`/profiles/${getSelectedProfile()}/accounts/${account.id}`)
await router.replace(`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`)
} catch (err) {
console.error(err)
} finally {
@ -101,7 +101,7 @@ async function doSubmit() {
</FormControl>
</FormGroup>
<FormActions @cancel="router.replace(`/profiles/${getSelectedProfile()}`)" :disabled="loading"
<FormActions @cancel="router.replace(`/profiles/${getSelectedProfile(route)}`)" :disabled="loading"
:submit-text="editing ? 'Save' : 'Add'" />
</AppForm>
</AppPage>

View File

@ -30,6 +30,9 @@ import { useRoute, useRouter, } from 'vue-router';
const route = useRoute()
const router = useRouter()
const transactionApi = new TransactionApiClient(getSelectedProfile(route))
const accountApi = new AccountApiClient(route)
const existingTransaction: Ref<TransactionDetail | null> = ref(null)
const editing = computed(() => {
return existingTransaction.value !== null || route.meta.title === 'Edit Transaction'
@ -80,14 +83,12 @@ watch(availableCurrencies, (newValue: Currency[]) => {
onMounted(async () => {
const dataClient = new DataApiClient()
const transactionClient = new TransactionApiClient()
const accountClient = new AccountApiClient()
// Fetch various collections of data needed for different user choices.
dataClient.getCurrencies().then(currencies => allCurrencies.value = currencies)
transactionClient.getVendors().then(vendors => availableVendors.value = vendors)
transactionClient.getAllTags().then(t => allTags.value = t)
accountClient.getAccounts().then(accounts => allAccounts.value = accounts)
transactionApi.getVendors().then(vendors => availableVendors.value = vendors)
transactionApi.getAllTags().then(t => allTags.value = t)
accountApi.getAccounts().then(accounts => allAccounts.value = accounts)
const transactionIdStr = route.params.id
@ -95,7 +96,7 @@ onMounted(async () => {
const transactionId = parseInt(transactionIdStr)
try {
loading.value = true
existingTransaction.value = await transactionClient.getTransaction(transactionId)
existingTransaction.value = await transactionApi.getTransaction(transactionId)
loadValuesFromExistingTransaction(existingTransaction.value)
} catch (err) {
console.error(err)
@ -133,7 +134,6 @@ async function doSubmit() {
attachmentIdsToRemove: removedAttachmentIds.value
}
const transactionApi = new TransactionApiClient()
let savedTransaction = null
try {
loading.value = true
@ -142,7 +142,7 @@ async function doSubmit() {
} else {
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) {
console.error(err)
} finally {
@ -156,9 +156,9 @@ async function doSubmit() {
*/
function doCancel() {
if (editing.value) {
router.replace(`/profiles/${getSelectedProfile()}/transactions/${existingTransaction.value?.id}`)
router.replace(`/profiles/${getSelectedProfile(route)}/transactions/${existingTransaction.value?.id}`)
} else {
router.replace(`/profiles/${getSelectedProfile()}`)
router.replace(`/profiles/${getSelectedProfile(route)}`)
}
}

View File

@ -5,14 +5,15 @@ import { getSelectedProfile } from '@/api/profile'
import AppButton from '@/components/AppButton.vue'
import HomeModule from '@/components/HomeModule.vue'
import { onMounted, ref, type Ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
const router = useRouter()
const route = useRoute()
const accounts: Ref<Account[]> = ref([])
onMounted(async () => {
const accountApi = new AccountApiClient()
const accountApi = new AccountApiClient(route)
accountApi.getAccounts().then(result => accounts.value = result)
.catch(err => console.error(err))
})
@ -33,7 +34,7 @@ onMounted(async () => {
<tbody>
<tr v-for="account in accounts" :key="account.id">
<td>
<RouterLink :to="`/profiles/${getSelectedProfile()}/accounts/${account.id}`">{{ account.name }}
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`">{{ account.name }}
</RouterLink>
</td>
<td>{{ account.currency.code }}</td>
@ -48,7 +49,7 @@ onMounted(async () => {
</table>
</template>
<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>
</template>
</HomeModule>

View File

@ -5,16 +5,17 @@ import ConfirmModal from '@/components/ConfirmModal.vue';
import HomeModule from '@/components/HomeModule.vue';
import { showAlert } from '@/util/alert';
import { onMounted, ref, useTemplateRef, type Ref } from 'vue';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter()
const route = useRoute()
const confirmDeleteModal = useTemplateRef('confirmDeleteModal')
const profile: Ref<Profile | undefined> = ref()
onMounted(async () => {
try {
profile.value = await new ProfileApiClient().getProfile(getSelectedProfile())
profile.value = await new ProfileApiClient().getProfile(getSelectedProfile(route))
} catch (err) {
console.error(err)
await showAlert("Failed to get profile.")
@ -23,7 +24,7 @@ onMounted(async () => {
})
async function deleteProfile() {
const currentProfileName = getSelectedProfile()
const currentProfileName = getSelectedProfile(route)
if (await confirmDeleteModal.value?.confirm()) {
const api = new ProfileApiClient()
try {

View File

@ -7,9 +7,10 @@ import AppButton from '@/components/AppButton.vue';
import HomeModule from '@/components/HomeModule.vue';
import PaginationControls from '@/components/PaginationControls.vue';
import { onMounted, ref, type Ref } from 'vue';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
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 })
onMounted(async () => {
@ -17,7 +18,7 @@ onMounted(async () => {
})
async function fetchPage(pageRequest: PageRequest) {
const api = new TransactionApiClient()
const api = new TransactionApiClient(getSelectedProfile(route))
try {
transactions.value = await api.getTransactions(pageRequest)
} catch (err) {
@ -50,18 +51,18 @@ async function fetchPage(pageRequest: PageRequest) {
<td>{{ tx.description }}</td>
<td>
<RouterLink v-if="tx.creditedAccount"
:to="`/profiles/${getSelectedProfile()}/accounts/${tx.creditedAccount.id}`">
:to="`/profiles/${getSelectedProfile(route)}/accounts/${tx.creditedAccount.id}`">
{{ tx.creditedAccount?.name }}
</RouterLink>
</td>
<td>
<RouterLink v-if="tx.debitedAccount"
:to="`/profiles/${getSelectedProfile()}/accounts/${tx.debitedAccount.id}`">
:to="`/profiles/${getSelectedProfile(route)}/accounts/${tx.debitedAccount.id}`">
{{ tx.debitedAccount?.name }}
</RouterLink>
</td>
<td>
<RouterLink :to="`/profiles/${getSelectedProfile()}/transactions/${tx.id}`">View</RouterLink>
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/transactions/${tx.id}`">View</RouterLink>
</td>
</tr>
</tbody>
@ -69,7 +70,8 @@ async function fetchPage(pageRequest: PageRequest) {
<PaginationControls :page="transactions" @update="pr => fetchPage(pr)"></PaginationControls>
</template>
<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>
</template>
</HomeModule>