Skip to content

Commit

Permalink
- make transaction-form read-only for split transactions
Browse files Browse the repository at this point in the history
- better UI in transactions-list for split-transactions
- in transactions-list show all tags and categories for split-transactions
- fix app-icon height not respecting size prop
- start transition from lodash array functions to Array.prototype defined ones
  • Loading branch information
cioraneanu committed Dec 12, 2024
1 parent 4b4c3d3 commit e8522a0
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 58 deletions.
4 changes: 4 additions & 0 deletions front/assets/styles/theme-dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,7 @@
border: 1px dashed #666;
}


.van-theme-dark .split-transaction-badge {
background: #B71C1C;
}
13 changes: 13 additions & 0 deletions front/assets/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -998,4 +998,17 @@ img, svg {

.app-card-info {
border: 1px dashed #777;
}

.split-transaction-badge {
background: #FF7043;
color: #fff;
border-radius: 8px;
padding: 2px 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 400;
line-height: 16px;
}
50 changes: 24 additions & 26 deletions front/components/list-items/transaction-list-item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<!-- <div class="separator"></div>-->

<div class="second_column flex-1">
<div v-if="isSplitPayment && props.isDetailedMode" class="mt-1 display-flex">
<transaction-split-badge />
</div>

<div class="flex-center-vertical gap-2">
<transaction-type-dot :transactionType="transactionType" class="ml-5" />
<div v-if="description" class="list-item-title">{{ description }}</div>
Expand All @@ -24,9 +28,11 @@
</div>
</div>

<div v-if="category && props.isDetailedMode" class="list-item-subtitle">
<app-icon :icon="Category.getIcon(category) ?? TablerIconConstants.category" :size="20" />
{{ Category.getDisplayName(category) }}
<div v-if="categories && props.isDetailedMode" class="list-item-subtitle gap-2">
<div v-for="category in categories">
<app-icon :icon="Category.getIcon(category) ?? TablerIconConstants.category" :size="20" />
{{ Category.getDisplayName(category) }}
</div>
</div>

<div v-if="notes && props.isDetailedMode" class="list-item-subtitle">
Expand All @@ -40,33 +46,16 @@
<div class="list-item-subtitle ml-5">{{ Tag.getDisplayNameEllipsized(tag, 10) }}</div>
</div>
</div>

<div v-if="isSplitPayment && props.isDetailedMode">
<van-tag class="" type="warning"> Split payment</van-tag>
</div>
</div>

<!-- <div class="separator"></div>-->

<div class="third_column">
<div class="font-weight-700 text-size-16">{{ transactionAmount }} {{ transactionCurrency }}</div>

<transaction-list-item-hero-icon v-if="props.isDetailedMode" :value="props.value" />

<!-- <div-->
<!-- v-if="heroIcon.length > 0 && props.isDetailedMode"-->
<!-- class="hero-icons-section gap-1 flex-center-vertical">-->
<!-- <app-icon-->
<!-- v-for="(icon, index) in heroIcon"-->
<!-- :icon="icon"-->
<!-- :size="30"/>-->
<!-- </div>-->

<div class="flex-center-vertical text-muted text-size-12">
{{ dateFormatted }}
</div>

<!-- <div v-if="props.isDetailedMode" class="day-of-week" style="margin-top: -2px">{{ dateWeekdayName }}</div>-->
</div>
</div>
</template>
Expand All @@ -89,6 +78,8 @@ import TablerIconConstants from '~/constants/TablerIconConstants'
import Tag from '../../models/Tag.js'
import Account from '~/models/Account.js'
import TransactionListItemHeroIcon from '~/components/list-items/transaction-list-item-hero-icon.vue'
import { uniqBy } from 'lodash/array.js'
import TransactionSplitBadge from '~/components/transaction/transaction-split-badge.vue'
const props = defineProps({
value: Object,
Expand Down Expand Up @@ -118,15 +109,22 @@ const displayedAccounts = computed(() => {
})
const description = computed(() => _.get(firstTransaction.value, 'description', ' - '))
const category = computed(() => _.get(firstTransaction.value, 'category'))
// const category = computed(() => _.get(firstTransaction.value, 'category'))
const categories = computed(() => {
return transactions.value
.map((item) => item.category)
.flat()
.filter(Boolean)
.uniqBy('id')
})
const notes = computed(() => _.get(firstTransaction.value, 'notes', ' - '))
// const tags = computed(() => {
// let list = firstTransaction.value.tags ?? []
// return list.map(item => `${get(item, 'attributes.tag')}`)
// })
const tags = computed(() => {
return firstTransaction.value.tags ?? []
return transactions.value
.map((item) => item.tags)
.flat()
.filter(Boolean)
.uniqBy('id')
})
const isTodo = computed(() => tags.value.some((tag) => get(tag, 'attributes.is_todo')))
Expand Down
6 changes: 5 additions & 1 deletion front/components/transaction/transaction-amount-field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
</div>
</template>

<table v-if="showQuickButtons" class="transaction-amount-table-buttons">
<table v-if="showQuickButtons && !disabled" class="transaction-amount-table-buttons">
<tbody>
<tr>
<td v-for="quickButton in quickButtons">
Expand Down Expand Up @@ -146,6 +146,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false
}
})
const transactionInputClass = computed(() => {
Expand Down
10 changes: 10 additions & 0 deletions front/components/transaction/transaction-split-badge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<div class="split-transaction-badge gap-1">
<app-icon :icon="TablerIconConstants.lock" :size="14" />
<div class="">Split transaction</div>
</div>
</template>

<script setup>
import TablerIconConstants from '~/constants/TablerIconConstants'
</script>
3 changes: 1 addition & 2 deletions front/components/ui-kit/app-icon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const props = defineProps({
},
})
const style = computed(() => `width: ${props.size}px`)
const style = computed(() => `width: ${props.size}px; height: ${props.size}px`)
const isColorInvertable = computed(() => {
if (Icon.isTypeTabler(props.icon) || Icon.isTypeAvatar(props.icon)) {
Expand All @@ -29,4 +29,3 @@ const isColorInvertable = computed(() => {
})
</script>

<style></style>
1 change: 1 addition & 0 deletions front/constants/TablerIconConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const icons = {

eyeHidden: 'IconEyeX',
eyeVisible: 'IconEye',
lock: 'IconLock',


// ------ Icon Select -----
Expand Down
3 changes: 3 additions & 0 deletions front/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Array<T> {
uniqBy(field): T[];
}
34 changes: 15 additions & 19 deletions front/pages/transactions/[[id]].vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@

<transaction-type-tabs v-model="type" class="mx-3 mt-1 mb-1" />

<van-form :name="formName" class="transaction-form-group" ref="form" @submit="saveItem" @failed="onValidationError">
<van-form :disabled="isSplitTransaction" :name="formName" class="transaction-form-group" ref="form" @submit="saveItem" @failed="onValidationError">
<van-cell-group inset class="mt-0 flex-column display-flex">
<template #title v-if="isSplitPayment">
<div>
<van-tag class="ml-5" type="warning">Split payment</van-tag>
</div>
</template>

<div v-if="isSplitTransaction" class="display-flex ml-3 mt-3">
<transaction-split-badge />
</div>

<transaction-amount-field
required
Expand All @@ -31,6 +30,7 @@
name="amount"
:rules="[{ required: true, message: 'Amount is required' }]"
:style="getStyleForField(FORM_CONSTANTS_TRANSACTION_FIELDS.TRANSACTION_FORM_FIELD_AMOUNT)"
:disabled="isSplitTransaction"
/>

<account-select
Expand Down Expand Up @@ -77,14 +77,9 @@
<tag-select v-model="tags" :style="getStyleForField(FORM_CONSTANTS_TRANSACTION_FIELDS.TRANSACTION_FORM_FIELD_TAG)" />

<div :style="getStyleForField(FORM_CONSTANTS_TRANSACTION_FIELDS.TRANSACTION_FORM_FIELD_DATE)">
<app-date-time-grid
v-model="date"
name="date"
:rules="[{ required: true, message: 'Date is required' }]"
required
/>

<div class="px-3 flex-center-vertical gap-1">
<app-date-time-grid v-model="date" name="date" :rules="[{ required: true, message: 'Date is required' }]" required />

<div v-if="!isSplitTransaction" class="px-3 flex-center-vertical gap-1">
<van-button size="small" @click="onSubDay">-1 day</van-button>
<van-button size="small" @click="onToday">Today</van-button>
<van-button size="small" @click="onAddDay">+1 day</van-button>
Expand All @@ -106,22 +101,22 @@
</van-cell-group>

<div style="margin: 16px; position: relative">
<app-button-form-delete class="mt-10" v-if="itemId" @click="onDelete" />
<app-button-form-delete class="mt-10" v-if="itemId && !isSplitTransaction" @click="onDelete" />

<div class="display-flex gap-1">
<van-button v-if="itemId && !isSplitPayment" @click="onCreateClone" block type="default" class="mt-2 flex-1">
<van-button v-if="itemId && !isSplitTransaction" @click="onCreateClone" block type="default" class="mt-2 flex-1">
<app-icon :icon="TablerIconConstants.clone" />
Clone
</van-button>

<van-button v-if="itemId && !isSplitPayment" @click="onCreateTransactionTemplate" block type="default" class="mt-2 flex-1">
<van-button v-if="itemId && !isSplitTransaction" @click="onCreateTransactionTemplate" block type="default" class="mt-2 flex-1">
<app-icon :icon="TablerIconConstants.transactionTemplate" />
Make template
</van-button>
</div>
</div>

<app-button-form-save />
<app-button-form-save v-if="!isSplitTransaction" />
</van-form>

<app-card-info style="order: 99">
Expand Down Expand Up @@ -154,6 +149,7 @@ import tag from '~/models/Tag'
import { addDays, endOfMonth, startOfMonth } from 'date-fns'
import TransactionRepository from '~/repository/TransactionRepository.js'
import TransactionTransformer from '~/transformers/TransactionTransformer.js'
import TransactionSplitBadge from '~/components/transaction/transaction-split-badge.vue'
const refAmount = ref(null)
Expand Down Expand Up @@ -195,7 +191,7 @@ const { amount, amountForeign, date, tags, description, notes, budget, accountSo
const transactions = computed(() => _.get(item.value, 'attributes.transactions', []))
const firstTransaction = computed(() => _.head(transactions.value))
const isSplitPayment = computed(() => transactions.value.length > 1)
const isSplitTransaction = computed(() => transactions.value.length > 1)
const accountSourceAllowedTypes = computed(() => Account.getAccountTypesForTransactionTypeSource(type.value))
const accountDestinationAllowedTypes = computed(() => Account.getAccountTypesForTransactionTypeDestination(type.value))
// const accountSourceAllowedTypes = computed(() => [])
Expand Down
5 changes: 5 additions & 0 deletions front/plugins/array-extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default defineNuxtPlugin((nuxtApp) => {
Array.prototype.uniqBy = function (field) {
return [...new Map(this.map((item) => [item[field], item])).values()]
}
})
10 changes: 1 addition & 9 deletions front/plugins/language.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,4 @@ Locale.use('en-US', enUS)

import '@vant/touch-emulator'

export default defineNuxtPlugin((nuxtApp) => {
// const vuetify = createVuetify({
// ssr: true,
// components,
// directives,
// })
//
// nuxtApp.vueApp.use(vuetify)
})
export default defineNuxtPlugin((nuxtApp) => {})
4 changes: 3 additions & 1 deletion front/plugins/register-tabler-icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ import {
IconPercentage30,
IconMoneybag,
IconBasket,
IconCopy
IconCopy,
IconLock
} from '@tabler/icons-vue'

export default defineNuxtPlugin((nuxtApp) => {
Expand Down Expand Up @@ -109,6 +110,7 @@ export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('IconCoin', IconCoin)
nuxtApp.vueApp.component('IconBasket', IconBasket)
nuxtApp.vueApp.component('IconCopy', IconCopy)
nuxtApp.vueApp.component('IconLock', IconLock)

// for (let iconName in tablerIcons) {
// nuxtApp.vueApp.component(iconName, tablerIcons[iconName])
Expand Down

0 comments on commit e8522a0

Please sign in to comment.