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 "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> <template>
<q-card> <q-card v-bind:class="{ 'bg-grey': isReversed }">
<q-card-actions align="right"> <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 <q-btn
:color="color()" color="negative"
aria-label="Reverse transaction"
icon="mdi-trash-can" icon="mdi-trash-can"
aria-label="Löschen" square
:disable="disabled()" :disable="!canReverse"
@click="reverse(transaction)" @click="reverse"
/> />
</q-card-actions> </div>
<q-card-section>
<span>{{ timeStr }}: {{ transaction.amount }}</span>
</q-card-section> </q-card-section>
</q-card> </q-card>
</template> </template>
<script lang="ts"> <script lang="ts">
// TODO: Better styling import { ref, computed, defineComponent, onUnmounted, onMounted } from '@vue/composition-api';
import { ref, computed, defineComponent, onUnmounted } from '@vue/composition-api';
import { hasPermission } from 'src/utils/permission'; import { hasPermission } from 'src/utils/permission';
import { formatDateTime } from 'src/utils/datetime'; import { formatDateTime } from 'src/utils/datetime';
import { StateInterfaceBalance } from 'src/plugins/balance/store/balance'; import { StateInterfaceBalance } from 'src/plugins/balance/store/balance';
@ -30,36 +39,60 @@ interface Props {
export default defineComponent({ export default defineComponent({
name: 'Transaction', name: 'Transaction',
props: ['transaction'], props: {
transaction: {
type: Object,
required: true
}
},
watch: { transaction: 'refreshText' },
setup(props: Props, { root, emit }) { setup(props: Props, { root, emit }) {
const now = ref(Date.now()); const now = ref(Date.now());
const ival = setInterval(() => (now.value = Date.now()), 1000); const ival = setInterval(() => (now.value = Date.now()), 1000);
const store: Store<StateInterfaceBalance> = <Store<StateInterfaceBalance>>root.$store; const store: Store<StateInterfaceBalance> = <Store<StateInterfaceBalance>>root.$store;
const text = ref('');
onUnmounted(() => clearInterval(ival)); onUnmounted(() => clearInterval(ival));
onMounted(() => refreshText());
function canReverse(transaction: FG.Transaction) { const isNegative = () => props.transaction.sender_id === store.state.user.currentUser?.userid;
return (
hasPermission('balance_reversal', store) || const refreshText = async () => {
(transaction.sender_id === store.state.user.currentUser?.userid && if (isNegative()) {
Date.now() - transaction.time.getTime() < 10000) 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}`;
}
}
};
const isReversed = computed(() => props.transaction.reversal != undefined);
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 color() { function reverse() {
return canReverse(props.transaction) ? 'negative' : 'grey'; if (canReverse.value)
}
function disabled() {
return !canReverse(props.transaction);
}
function reverse(transaction: FG.Transaction) {
if (canReverse(transaction))
store store
.dispatch('balance/revert', transaction) .dispatch('balance/revert', props.transaction)
.then(() => { .then(() => {
emit('reversed', transaction.id); emit('update:transaction', props.transaction);
}) })
.catch(error => console.log(error)); .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 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> </script>

View File

@ -56,8 +56,9 @@
</q-card-section> </q-card-section>
</q-card> </q-card>
</div> </div>
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-sm-4 col-xs-6"> <div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-md-4 col-sm-6">
<Transaction :transaction="transaction" @reversed="reversed" /> <!-- TODO: In Vue3 use v-model:transaction="..." -->
<Transaction :transaction.sync="transactions[index]" />
</div> </div>
</q-page> </q-page>
</template> </template>
@ -80,7 +81,7 @@ export default defineComponent({
const amount = ref<number>(0); const amount = ref<number>(0);
const showAddShortcut = ref(false); 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 user = ref(store.state.user.currentUser);
const shortCuts = ref(store.state.balance.shortcuts); const shortCuts = ref(store.state.balance.shortcuts);
@ -89,7 +90,7 @@ export default defineComponent({
); );
function addShortcut() { 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) { function removeShortcut(shortcut: number) {
void store.dispatch('balance/removeShortcut', shortcut); void store.dispatch('balance/removeShortcut', shortcut);
@ -100,19 +101,9 @@ export default defineComponent({
function changeBalance(amount: number) { function changeBalance(amount: number) {
store store
.dispatch('balance/changeBalance', { amount: amount, user: user.value?.userid }) .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)); .catch(err => console.log(err));
} }
function reversed(id: number) {
transactions.value = transactions.value.filter(t => t.id != id);
}
return { return {
user, user,
addShortcut, addShortcut,
@ -123,7 +114,6 @@ export default defineComponent({
amount, amount,
showSelector, showSelector,
shortCuts, shortCuts,
reversed,
userUpdated userUpdated
}; };
} }

View File

@ -31,7 +31,7 @@
</q-card> </q-card>
</div> </div>
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-sm-4 col-xs-6"> <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> </div>
</q-page> </q-page>
</template> </template>
@ -56,7 +56,7 @@ export default defineComponent({
const sender = ref(store.state.user.currentUser); const sender = ref(store.state.user.currentUser);
const receiver = ref<FG.User | undefined>(undefined); const receiver = ref<FG.User | undefined>(undefined);
const amount = ref<number>(0); const amount = ref<number>(0);
const transactions = ref<FG.Transaction[]>([]); const transactions = computed(() => store.state.balance.transactions.slice().reverse());
const sendDisabled = computed(() => { const sendDisabled = computed(() => {
return !( return !(
@ -75,10 +75,6 @@ export default defineComponent({
receiver.value = selectedUser; receiver.value = selectedUser;
} }
function reversed(id: number) {
transactions.value = transactions.value.filter(value => value.id != id);
}
function sendAmount() { function sendAmount() {
store store
.dispatch('balance/changeBalance', { .dispatch('balance/changeBalance', {
@ -86,11 +82,6 @@ export default defineComponent({
sender: sender.value?.userid, sender: sender.value?.userid,
user: receiver.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)); .catch(err => console.log(err));
} }
@ -103,8 +94,7 @@ export default defineComponent({
showSelector, showSelector,
senderUpdated, senderUpdated,
receiverUpdated, receiverUpdated,
sendDisabled, sendDisabled
reversed
}; };
} }
}); });