Reorders cards on the dashboard
Moves the pending expense approvals card to the top of the dashboard and the user balance card to a later position for better UX.
This commit is contained in:
parent
c7bc0c7904
commit
d1f22dfda8
1 changed files with 176 additions and 176 deletions
|
|
@ -62,6 +62,60 @@
|
||||||
</template>
|
</template>
|
||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
||||||
|
<!-- Pending Expense Entries (Super User Only) -->
|
||||||
|
<q-card v-if="isSuperUser && pendingExpenses.length > 0">
|
||||||
|
<q-card-section>
|
||||||
|
<h6 class="q-my-none q-mb-md">Pending Expense Approvals</h6>
|
||||||
|
<q-list separator>
|
||||||
|
<q-item v-for="entry in pendingExpenses" :key="entry.id">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="pending" color="orange" size="sm">
|
||||||
|
<q-tooltip>Pending approval</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{% raw %}{{ entry.description }}{% endraw %}</q-item-label>
|
||||||
|
<q-item-label caption>
|
||||||
|
{% raw %}{{ formatDate(entry.entry_date) }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="entry.meta && entry.meta.user_id">
|
||||||
|
User: {% raw %}{{ entry.meta.user_id.substring(0, 16) }}...{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="entry.reference" class="text-grey">
|
||||||
|
Ref: {% raw %}{{ entry.reference }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section side>
|
||||||
|
<q-item-label>{% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %}</q-item-label>
|
||||||
|
<q-item-label caption v-if="getEntryFiatAmount(entry)">
|
||||||
|
{% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section side>
|
||||||
|
<div class="q-gutter-xs">
|
||||||
|
<q-btn
|
||||||
|
size="sm"
|
||||||
|
color="positive"
|
||||||
|
@click="approveExpense(entry.id)"
|
||||||
|
:loading="entry.approving"
|
||||||
|
>
|
||||||
|
Approve
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
size="sm"
|
||||||
|
color="negative"
|
||||||
|
@click="rejectExpense(entry.id)"
|
||||||
|
:loading="entry.rejecting"
|
||||||
|
>
|
||||||
|
Reject
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
<!-- Quick Actions -->
|
<!-- Quick Actions -->
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
|
|
@ -101,58 +155,6 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<!-- User Balance Card -->
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
<div class="row items-center no-wrap q-mb-sm">
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="q-my-none">Your Balance</h6>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<q-btn flat round icon="refresh" @click="loadBalance">
|
|
||||||
<q-tooltip>Refresh balance</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="balance !== null">
|
|
||||||
<div class="text-h4" :class="isSuperUser ? (balance.balance >= 0 ? 'text-negative' : 'text-positive') : (balance.balance >= 0 ? 'text-positive' : 'text-negative')">
|
|
||||||
{% raw %}{{ formatSats(Math.abs(balance.balance)) }} sats{% endraw %}
|
|
||||||
</div>
|
|
||||||
<div v-if="balance.fiat_balances && Object.keys(balance.fiat_balances).length > 0" class="text-h6 q-mt-sm">
|
|
||||||
<span v-for="(amount, currency) in balance.fiat_balances" :key="currency" class="q-mr-md">
|
|
||||||
{% raw %}{{ formatFiat(Math.abs(amount), currency) }}{% endraw %}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="text-subtitle2" v-if="isSuperUser">
|
|
||||||
{% raw %}{{ balance.balance > 0 ? 'Total you owe' : balance.balance < 0 ? 'Total owed to you' : 'No outstanding balances' }}{% endraw %}
|
|
||||||
</div>
|
|
||||||
<div class="text-subtitle2" v-else>
|
|
||||||
{% raw %}{{ balance.balance >= 0 ? 'Castle owes you' : 'You owe Castle' }}{% endraw %}
|
|
||||||
</div>
|
|
||||||
<div class="q-mt-md q-gutter-sm">
|
|
||||||
<q-btn
|
|
||||||
v-if="balance.balance < 0 && !isSuperUser"
|
|
||||||
color="primary"
|
|
||||||
@click="showPayBalanceDialog"
|
|
||||||
>
|
|
||||||
Pay Balance
|
|
||||||
</q-btn>
|
|
||||||
<q-btn
|
|
||||||
v-if="balance.balance > 0 && !isSuperUser"
|
|
||||||
color="secondary"
|
|
||||||
@click="showManualPaymentDialog"
|
|
||||||
>
|
|
||||||
Request Manual Payment
|
|
||||||
</q-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<q-spinner color="primary" size="md"></q-spinner>
|
|
||||||
Loading balance...
|
|
||||||
</div>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
|
|
||||||
<!-- User Balances Breakdown (Super User Only) -->
|
<!-- User Balances Breakdown (Super User Only) -->
|
||||||
<q-card v-if="isSuperUser && outstandingUserBalances.length > 0">
|
<q-card v-if="isSuperUser && outstandingUserBalances.length > 0">
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
|
|
@ -222,57 +224,55 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<!-- Pending Expense Entries (Super User Only) -->
|
<!-- User Balance Card -->
|
||||||
<q-card v-if="isSuperUser && pendingExpenses.length > 0">
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="q-my-none q-mb-md">Pending Expense Approvals</h6>
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
<q-list separator>
|
<div class="col">
|
||||||
<q-item v-for="entry in pendingExpenses" :key="entry.id">
|
<h6 class="q-my-none">Your Balance</h6>
|
||||||
<q-item-section avatar>
|
</div>
|
||||||
<q-icon name="pending" color="orange" size="sm">
|
<div class="col-auto">
|
||||||
<q-tooltip>Pending approval</q-tooltip>
|
<q-btn flat round icon="refresh" @click="loadBalance">
|
||||||
</q-icon>
|
<q-tooltip>Refresh balance</q-tooltip>
|
||||||
</q-item-section>
|
</q-btn>
|
||||||
<q-item-section>
|
</div>
|
||||||
<q-item-label>{% raw %}{{ entry.description }}{% endraw %}</q-item-label>
|
</div>
|
||||||
<q-item-label caption>
|
<div v-if="balance !== null">
|
||||||
{% raw %}{{ formatDate(entry.entry_date) }}{% endraw %}
|
<div class="text-h4" :class="isSuperUser ? (balance.balance >= 0 ? 'text-negative' : 'text-positive') : (balance.balance >= 0 ? 'text-positive' : 'text-negative')">
|
||||||
</q-item-label>
|
{% raw %}{{ formatSats(Math.abs(balance.balance)) }} sats{% endraw %}
|
||||||
<q-item-label caption v-if="entry.meta && entry.meta.user_id">
|
</div>
|
||||||
User: {% raw %}{{ entry.meta.user_id.substring(0, 16) }}...{% endraw %}
|
<div v-if="balance.fiat_balances && Object.keys(balance.fiat_balances).length > 0" class="text-h6 q-mt-sm">
|
||||||
</q-item-label>
|
<span v-for="(amount, currency) in balance.fiat_balances" :key="currency" class="q-mr-md">
|
||||||
<q-item-label caption v-if="entry.reference" class="text-grey">
|
{% raw %}{{ formatFiat(Math.abs(amount), currency) }}{% endraw %}
|
||||||
Ref: {% raw %}{{ entry.reference }}{% endraw %}
|
</span>
|
||||||
</q-item-label>
|
</div>
|
||||||
</q-item-section>
|
<div class="text-subtitle2" v-if="isSuperUser">
|
||||||
<q-item-section side>
|
{% raw %}{{ balance.balance > 0 ? 'Total you owe' : balance.balance < 0 ? 'Total owed to you' : 'No outstanding balances' }}{% endraw %}
|
||||||
<q-item-label>{% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %}</q-item-label>
|
</div>
|
||||||
<q-item-label caption v-if="getEntryFiatAmount(entry)">
|
<div class="text-subtitle2" v-else>
|
||||||
{% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %}
|
{% raw %}{{ balance.balance >= 0 ? 'Castle owes you' : 'You owe Castle' }}{% endraw %}
|
||||||
</q-item-label>
|
</div>
|
||||||
</q-item-section>
|
<div class="q-mt-md q-gutter-sm">
|
||||||
<q-item-section side>
|
<q-btn
|
||||||
<div class="q-gutter-xs">
|
v-if="balance.balance < 0 && !isSuperUser"
|
||||||
<q-btn
|
color="primary"
|
||||||
size="sm"
|
@click="showPayBalanceDialog"
|
||||||
color="positive"
|
>
|
||||||
@click="approveExpense(entry.id)"
|
Pay Balance
|
||||||
:loading="entry.approving"
|
</q-btn>
|
||||||
>
|
<q-btn
|
||||||
Approve
|
v-if="balance.balance > 0 && !isSuperUser"
|
||||||
</q-btn>
|
color="secondary"
|
||||||
<q-btn
|
@click="showManualPaymentDialog"
|
||||||
size="sm"
|
>
|
||||||
color="negative"
|
Request Manual Payment
|
||||||
@click="rejectExpense(entry.id)"
|
</q-btn>
|
||||||
:loading="entry.rejecting"
|
</div>
|
||||||
>
|
</div>
|
||||||
Reject
|
<div v-else>
|
||||||
</q-btn>
|
<q-spinner color="primary" size="md"></q-spinner>
|
||||||
</div>
|
Loading balance...
|
||||||
</q-item-section>
|
</div>
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
@ -319,6 +319,80 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
<!-- Recent Transactions -->
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="q-my-none">Recent Transactions</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<q-btn flat round icon="refresh" @click="loadTransactions">
|
||||||
|
<q-tooltip>Refresh transactions</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-list v-if="transactions.length > 0" separator>
|
||||||
|
<q-item v-for="entry in transactions" :key="entry.id">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<!-- Transaction status flag -->
|
||||||
|
<q-icon v-if="entry.flag === '*'" name="check_circle" color="positive" size="sm">
|
||||||
|
<q-tooltip>Cleared</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
<q-icon v-else-if="entry.flag === '!'" name="pending" color="orange" size="sm">
|
||||||
|
<q-tooltip>Pending</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
<q-icon v-else-if="entry.flag === '#'" name="flag" color="red" size="sm">
|
||||||
|
<q-tooltip>Flagged - needs review</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
<q-icon v-else-if="entry.flag === 'x'" name="cancel" color="grey" size="sm">
|
||||||
|
<q-tooltip>Voided</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>
|
||||||
|
{% raw %}{{ entry.description }}{% endraw %}
|
||||||
|
<!-- Castle's perspective: Receivables are incoming (green), Payables are outgoing (red) -->
|
||||||
|
<q-badge v-if="isSuperUser && isReceivable(entry)" color="positive" class="q-ml-sm">
|
||||||
|
Receivable
|
||||||
|
</q-badge>
|
||||||
|
<q-badge v-else-if="isSuperUser && isPayable(entry)" color="negative" class="q-ml-sm">
|
||||||
|
Payable
|
||||||
|
</q-badge>
|
||||||
|
<!-- User's perspective: Receivables are outgoing (red), Payables are incoming (green) -->
|
||||||
|
<q-badge v-else-if="!isSuperUser && isReceivable(entry)" color="negative" class="q-ml-sm">
|
||||||
|
Payable
|
||||||
|
</q-badge>
|
||||||
|
<q-badge v-else-if="!isSuperUser && isPayable(entry)" color="positive" class="q-ml-sm">
|
||||||
|
Receivable
|
||||||
|
</q-badge>
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption>
|
||||||
|
{% raw %}{{ formatDate(entry.entry_date) }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="entry.reference" class="text-grey">
|
||||||
|
Ref: {% raw %}{{ entry.reference }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="entry.meta && Object.keys(entry.meta).length > 0" class="text-blue-grey-6">
|
||||||
|
<q-icon name="info" size="xs" class="q-mr-xs"></q-icon>
|
||||||
|
<span v-if="entry.meta.source">Source: {% raw %}{{ entry.meta.source }}{% endraw %}</span>
|
||||||
|
<span v-if="entry.meta.created_via" class="q-ml-sm">Via: {% raw %}{{ entry.meta.created_via }}{% endraw %}</span>
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section side>
|
||||||
|
<q-item-label>{% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %}</q-item-label>
|
||||||
|
<q-item-label caption v-if="getEntryFiatAmount(entry)">
|
||||||
|
{% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
<div v-else class="text-center q-pa-md text-grey">
|
||||||
|
No transactions yet
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
<!-- Balance Assertions (Super User Only) -->
|
<!-- Balance Assertions (Super User Only) -->
|
||||||
<q-card v-if="isSuperUser">
|
<q-card v-if="isSuperUser">
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
|
|
@ -565,80 +639,6 @@
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<!-- Recent Transactions -->
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
<div class="row items-center no-wrap q-mb-sm">
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="q-my-none">Recent Transactions</h6>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<q-btn flat round icon="refresh" @click="loadTransactions">
|
|
||||||
<q-tooltip>Refresh transactions</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<q-list v-if="transactions.length > 0" separator>
|
|
||||||
<q-item v-for="entry in transactions" :key="entry.id">
|
|
||||||
<q-item-section avatar>
|
|
||||||
<!-- Transaction status flag -->
|
|
||||||
<q-icon v-if="entry.flag === '*'" name="check_circle" color="positive" size="sm">
|
|
||||||
<q-tooltip>Cleared</q-tooltip>
|
|
||||||
</q-icon>
|
|
||||||
<q-icon v-else-if="entry.flag === '!'" name="pending" color="orange" size="sm">
|
|
||||||
<q-tooltip>Pending</q-tooltip>
|
|
||||||
</q-icon>
|
|
||||||
<q-icon v-else-if="entry.flag === '#'" name="flag" color="red" size="sm">
|
|
||||||
<q-tooltip>Flagged - needs review</q-tooltip>
|
|
||||||
</q-icon>
|
|
||||||
<q-icon v-else-if="entry.flag === 'x'" name="cancel" color="grey" size="sm">
|
|
||||||
<q-tooltip>Voided</q-tooltip>
|
|
||||||
</q-icon>
|
|
||||||
</q-item-section>
|
|
||||||
<q-item-section>
|
|
||||||
<q-item-label>
|
|
||||||
{% raw %}{{ entry.description }}{% endraw %}
|
|
||||||
<!-- Castle's perspective: Receivables are incoming (green), Payables are outgoing (red) -->
|
|
||||||
<q-badge v-if="isSuperUser && isReceivable(entry)" color="positive" class="q-ml-sm">
|
|
||||||
Receivable
|
|
||||||
</q-badge>
|
|
||||||
<q-badge v-else-if="isSuperUser && isPayable(entry)" color="negative" class="q-ml-sm">
|
|
||||||
Payable
|
|
||||||
</q-badge>
|
|
||||||
<!-- User's perspective: Receivables are outgoing (red), Payables are incoming (green) -->
|
|
||||||
<q-badge v-else-if="!isSuperUser && isReceivable(entry)" color="negative" class="q-ml-sm">
|
|
||||||
Payable
|
|
||||||
</q-badge>
|
|
||||||
<q-badge v-else-if="!isSuperUser && isPayable(entry)" color="positive" class="q-ml-sm">
|
|
||||||
Receivable
|
|
||||||
</q-badge>
|
|
||||||
</q-item-label>
|
|
||||||
<q-item-label caption>
|
|
||||||
{% raw %}{{ formatDate(entry.entry_date) }}{% endraw %}
|
|
||||||
</q-item-label>
|
|
||||||
<q-item-label caption v-if="entry.reference" class="text-grey">
|
|
||||||
Ref: {% raw %}{{ entry.reference }}{% endraw %}
|
|
||||||
</q-item-label>
|
|
||||||
<q-item-label caption v-if="entry.meta && Object.keys(entry.meta).length > 0" class="text-blue-grey-6">
|
|
||||||
<q-icon name="info" size="xs" class="q-mr-xs"></q-icon>
|
|
||||||
<span v-if="entry.meta.source">Source: {% raw %}{{ entry.meta.source }}{% endraw %}</span>
|
|
||||||
<span v-if="entry.meta.created_via" class="q-ml-sm">Via: {% raw %}{{ entry.meta.created_via }}{% endraw %}</span>
|
|
||||||
</q-item-label>
|
|
||||||
</q-item-section>
|
|
||||||
<q-item-section side>
|
|
||||||
<q-item-label>{% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %}</q-item-label>
|
|
||||||
<q-item-label caption v-if="getEntryFiatAmount(entry)">
|
|
||||||
{% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %}
|
|
||||||
</q-item-label>
|
|
||||||
</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
<div v-else class="text-center q-pa-md text-grey">
|
|
||||||
No transactions yet
|
|
||||||
</div>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue