release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
4 changed files with 77 additions and 63 deletions
Showing only changes of commit a787abdbc0 - Show all commits

View File

@ -24,5 +24,6 @@
"sortAttributes": false
}
},
"vetur.format.defaultFormatter.ts": "prettier-tslint"
"vetur.format.defaultFormatter.ts": "prettier-tslint",
"typescript.format.enable": false
}

View File

@ -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) }}&#8239;
</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>

View File

@ -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
};
}

View File

@ -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
};
}
});