Improved Transaction design and function
This commit is contained in:
		
							parent
							
								
									e366a25838
								
							
						
					
					
						commit
						a787abdbc0
					
				| 
						 | 
					@ -24,5 +24,6 @@
 | 
				
			||||||
      "sortAttributes": false
 | 
					      "sortAttributes": false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "vetur.format.defaultFormatter.ts": "prettier-tslint"
 | 
					  "vetur.format.defaultFormatter.ts": "prettier-tslint",
 | 
				
			||||||
 | 
					  "typescript.format.enable": false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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">
 | 
				
			||||||
      <q-btn
 | 
					      <div class="col text-center">
 | 
				
			||||||
        :color="color()"
 | 
					        <div
 | 
				
			||||||
        icon="mdi-trash-can"
 | 
					          v-bind:class="{ 'text-negative': isNegative() }"
 | 
				
			||||||
        aria-label="Löschen"
 | 
					          class="text-weight-bold"
 | 
				
			||||||
        :disable="disabled()"
 | 
					          style="font-size: 2em"
 | 
				
			||||||
        @click="reverse(transaction)"
 | 
					        >
 | 
				
			||||||
      />
 | 
					          <span v-if="isNegative()">-</span>{{ transaction.amount.toFixed(2) }} €
 | 
				
			||||||
    </q-card-actions>
 | 
					        </div>
 | 
				
			||||||
    <q-card-section>
 | 
					        <div>{{ text }}</div>
 | 
				
			||||||
      <span>{{ timeStr }}: {{ transaction.amount }}</span>
 | 
					        <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-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) ||
 | 
					 | 
				
			||||||
        (transaction.sender_id === store.state.user.currentUser?.userid &&
 | 
					 | 
				
			||||||
          Date.now() - transaction.time.getTime() < 10000)
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function color() {
 | 
					    const refreshText = async () => {
 | 
				
			||||||
      return canReverse(props.transaction) ? 'negative' : 'grey';
 | 
					      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() {
 | 
					    const isReversed = computed(() => props.transaction.reversal != undefined);
 | 
				
			||||||
      return !canReverse(props.transaction);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function reverse(transaction: FG.Transaction) {
 | 
					    const canReverse = computed(
 | 
				
			||||||
      if (canReverse(transaction))
 | 
					      () =>
 | 
				
			||||||
 | 
					        !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
 | 
					        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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue