Improved Transaction design and function
This commit is contained in:
parent
e366a25838
commit
a787abdbc0
|
@ -24,5 +24,6 @@
|
|||
"sortAttributes": false
|
||||
}
|
||||
},
|
||||
"vetur.format.defaultFormatter.ts": "prettier-tslint"
|
||||
"vetur.format.defaultFormatter.ts": "prettier-tslint",
|
||||
"typescript.format.enable": false
|
||||
}
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
<template>
|
||||
<q-card>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
:color="color()"
|
||||
icon="mdi-trash-can"
|
||||
aria-label="Löschen"
|
||||
:disable="disabled()"
|
||||
@click="reverse(transaction)"
|
||||
/>
|
||||
</q-card-actions>
|
||||
<q-card-section>
|
||||
<span>{{ timeStr }}: {{ transaction.amount }}</span>
|
||||
<q-card v-bind:class="{ 'bg-grey': isReversed }">
|
||||
<q-card-section class="row items-start justify-between">
|
||||
<div class="col text-center">
|
||||
<div
|
||||
v-bind:class="{ 'text-negative': isNegative() }"
|
||||
class="text-weight-bold"
|
||||
style="font-size: 2em"
|
||||
>
|
||||
<span v-if="isNegative()">-</span>{{ transaction.amount.toFixed(2) }} €
|
||||
</div>
|
||||
<div>{{ text }}</div>
|
||||
<div>{{ timeStr }}</div>
|
||||
</div>
|
||||
<div class="col" style="text-align: right">
|
||||
<q-btn
|
||||
color="negative"
|
||||
aria-label="Reverse transaction"
|
||||
icon="mdi-trash-can"
|
||||
square
|
||||
:disable="!canReverse"
|
||||
@click="reverse"
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// TODO: Better styling
|
||||
|
||||
import { ref, computed, defineComponent, onUnmounted } from '@vue/composition-api';
|
||||
import { ref, computed, defineComponent, onUnmounted, onMounted } from '@vue/composition-api';
|
||||
import { hasPermission } from 'src/utils/permission';
|
||||
import { formatDateTime } from 'src/utils/datetime';
|
||||
import { StateInterfaceBalance } from 'src/plugins/balance/store/balance';
|
||||
|
@ -30,36 +39,60 @@ interface Props {
|
|||
|
||||
export default defineComponent({
|
||||
name: 'Transaction',
|
||||
props: ['transaction'],
|
||||
props: {
|
||||
transaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
watch: { transaction: 'refreshText' },
|
||||
setup(props: Props, { root, emit }) {
|
||||
const now = ref(Date.now());
|
||||
const ival = setInterval(() => (now.value = Date.now()), 1000);
|
||||
const store: Store<StateInterfaceBalance> = <Store<StateInterfaceBalance>>root.$store;
|
||||
const text = ref('');
|
||||
|
||||
onUnmounted(() => clearInterval(ival));
|
||||
onMounted(() => refreshText());
|
||||
|
||||
function canReverse(transaction: FG.Transaction) {
|
||||
return (
|
||||
hasPermission('balance_reversal', store) ||
|
||||
(transaction.sender_id === store.state.user.currentUser?.userid &&
|
||||
Date.now() - transaction.time.getTime() < 10000)
|
||||
);
|
||||
}
|
||||
const isNegative = () => props.transaction.sender_id === store.state.user.currentUser?.userid;
|
||||
|
||||
function color() {
|
||||
return canReverse(props.transaction) ? 'negative' : 'grey';
|
||||
}
|
||||
const refreshText = async () => {
|
||||
if (isNegative()) {
|
||||
text.value = 'Anschreiben';
|
||||
if (props.transaction.receiver_id !== null) {
|
||||
const user = <FG.User>await store.dispatch('user/getUser', {
|
||||
userid: props.transaction.receiver_id
|
||||
});
|
||||
text.value = `Gesendet an ${user.display_name}`;
|
||||
}
|
||||
} else {
|
||||
text.value = 'Gutschrift';
|
||||
if (props.transaction.sender_id !== null) {
|
||||
const user = <FG.User>await store.dispatch('user/getUser', {
|
||||
userid: props.transaction.sender_id
|
||||
});
|
||||
text.value = `Bekommen von ${user.display_name}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function disabled() {
|
||||
return !canReverse(props.transaction);
|
||||
}
|
||||
const isReversed = computed(() => props.transaction.reversal != undefined);
|
||||
|
||||
function reverse(transaction: FG.Transaction) {
|
||||
if (canReverse(transaction))
|
||||
const canReverse = computed(
|
||||
() =>
|
||||
!isReversed.value &&
|
||||
(hasPermission('balance_reversal', store) ||
|
||||
(props.transaction.sender_id === store.state.user.currentUser?.userid &&
|
||||
now.value - props.transaction.time.getTime() < 10000))
|
||||
);
|
||||
|
||||
function reverse() {
|
||||
if (canReverse.value)
|
||||
store
|
||||
.dispatch('balance/revert', transaction)
|
||||
.dispatch('balance/revert', props.transaction)
|
||||
.then(() => {
|
||||
emit('reversed', transaction.id);
|
||||
emit('update:transaction', props.transaction);
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
}
|
||||
|
@ -70,7 +103,7 @@ export default defineComponent({
|
|||
return formatDateTime(props.transaction.time, elapsed > 12 * 60 * 60, true, true) + ' Uhr';
|
||||
});
|
||||
|
||||
return { timeStr, disabled, color, reverse };
|
||||
return { timeStr, reverse, isNegative, text, refreshText, canReverse, isReversed };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -56,8 +56,9 @@
|
|||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-sm-4 col-xs-6">
|
||||
<Transaction :transaction="transaction" @reversed="reversed" />
|
||||
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-md-4 col-sm-6">
|
||||
<!-- TODO: In Vue3 use v-model:transaction="..." -->
|
||||
<Transaction :transaction.sync="transactions[index]" />
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
@ -80,7 +81,7 @@ export default defineComponent({
|
|||
|
||||
const amount = ref<number>(0);
|
||||
const showAddShortcut = ref(false);
|
||||
const transactions = ref<FG.Transaction[]>([]);
|
||||
const transactions = computed(() => store.state.balance.transactions.slice().reverse());
|
||||
const user = ref(store.state.user.currentUser);
|
||||
const shortCuts = ref(store.state.balance.shortcuts);
|
||||
|
||||
|
@ -89,7 +90,7 @@ export default defineComponent({
|
|||
);
|
||||
|
||||
function addShortcut() {
|
||||
void store.dispatch('balance/addShortcut', amount.value * -1);
|
||||
if (amount.value != 0) void store.dispatch('balance/addShortcut', amount.value * -1);
|
||||
}
|
||||
function removeShortcut(shortcut: number) {
|
||||
void store.dispatch('balance/removeShortcut', shortcut);
|
||||
|
@ -100,19 +101,9 @@ export default defineComponent({
|
|||
function changeBalance(amount: number) {
|
||||
store
|
||||
.dispatch('balance/changeBalance', { amount: amount, user: user.value?.userid })
|
||||
.then((transaction: FG.Transaction) => {
|
||||
if (transactions.value.length > 5) transactions.value.pop();
|
||||
transaction.time = new Date(transaction.time);
|
||||
transactions.value.unshift(transaction);
|
||||
console.log(transactions.value);
|
||||
})
|
||||
.catch(err => console.log(err));
|
||||
}
|
||||
|
||||
function reversed(id: number) {
|
||||
transactions.value = transactions.value.filter(t => t.id != id);
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
addShortcut,
|
||||
|
@ -123,7 +114,6 @@ export default defineComponent({
|
|||
amount,
|
||||
showSelector,
|
||||
shortCuts,
|
||||
reversed,
|
||||
userUpdated
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</q-card>
|
||||
</div>
|
||||
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-sm-4 col-xs-6">
|
||||
<Transaction :transaction="transaction" @reversed="reversed" />
|
||||
<Transaction :transaction.sync="transactions[index]" />
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
@ -56,7 +56,7 @@ export default defineComponent({
|
|||
const sender = ref(store.state.user.currentUser);
|
||||
const receiver = ref<FG.User | undefined>(undefined);
|
||||
const amount = ref<number>(0);
|
||||
const transactions = ref<FG.Transaction[]>([]);
|
||||
const transactions = computed(() => store.state.balance.transactions.slice().reverse());
|
||||
|
||||
const sendDisabled = computed(() => {
|
||||
return !(
|
||||
|
@ -75,10 +75,6 @@ export default defineComponent({
|
|||
receiver.value = selectedUser;
|
||||
}
|
||||
|
||||
function reversed(id: number) {
|
||||
transactions.value = transactions.value.filter(value => value.id != id);
|
||||
}
|
||||
|
||||
function sendAmount() {
|
||||
store
|
||||
.dispatch('balance/changeBalance', {
|
||||
|
@ -86,11 +82,6 @@ export default defineComponent({
|
|||
sender: sender.value?.userid,
|
||||
user: receiver.value?.userid
|
||||
})
|
||||
.then((transaction: FG.Transaction) => {
|
||||
if (transactions.value.length > 5) transactions.value.pop();
|
||||
transaction.time = new Date(transaction.time);
|
||||
transactions.value.unshift(transaction);
|
||||
})
|
||||
.catch(err => console.log(err));
|
||||
}
|
||||
|
||||
|
@ -103,8 +94,7 @@ export default defineComponent({
|
|||
showSelector,
|
||||
senderUpdated,
|
||||
receiverUpdated,
|
||||
sendDisabled,
|
||||
reversed
|
||||
sendDisabled
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue