mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-03-13 19:37:42 +01:00
Chart polish (#2973)
This commit is contained in:
parent
60de308c8f
commit
c08623277e
7 changed files with 170 additions and 130 deletions
|
@ -440,6 +440,8 @@ async def get_payments_daily_stats(
|
|||
balance_total: float = 0
|
||||
|
||||
_none = PaymentDailyStats(date=datetime.now(timezone.utc))
|
||||
if len(data_in) == 0 and len(data_out) == 0:
|
||||
return []
|
||||
if len(data_in) == 0:
|
||||
data_in = [_none]
|
||||
if len(data_out) == 0:
|
||||
|
|
|
@ -4,34 +4,43 @@
|
|||
<!---->
|
||||
{% block scripts %} {{ window_vars(user) }}{% endblock %} {% block page %}
|
||||
|
||||
<div class="row q-col-gutter-md q-mb-md">
|
||||
<div class="col-12">
|
||||
<q-card>
|
||||
<div>
|
||||
<div class="q-gutter-y-md">
|
||||
<q-tabs v-model="tab" align="left">
|
||||
<q-tab
|
||||
name="user"
|
||||
:label="$t('account_settings')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
<q-tab
|
||||
name="theme"
|
||||
:label="$t('look_and_feel')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
<q-tab
|
||||
name="api_acls"
|
||||
:label="$t('access_control_list')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
</q-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row q-col-gutter-md">
|
||||
<div v-if="user" class="col-md-12 col-lg-6 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<q-tabs v-model="tab" align="justify">
|
||||
<q-tab
|
||||
name="user"
|
||||
:label="$t('account_settings')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
<q-tab
|
||||
name="theme"
|
||||
:label="$t('look_and_feel')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
<q-tab
|
||||
name="api_acls"
|
||||
:label="$t('access_control_list')"
|
||||
@update="val => tab = val.name"
|
||||
></q-tab>
|
||||
</q-tabs>
|
||||
<q-tab-panels v-model="tab">
|
||||
<q-tab-panel name="user">
|
||||
<div v-if="credentialsData.show">
|
||||
<q-separator></q-separator>
|
||||
|
||||
<q-card-section>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
@ -132,11 +141,10 @@
|
|||
</q-card-section>
|
||||
</div>
|
||||
<div v-else>
|
||||
<q-card-section>
|
||||
<q-card-section v-if="user.extra.picture">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<q-img
|
||||
v-if="user.extra.picture"
|
||||
style="max-width: 100px"
|
||||
:src="user.extra.picture"
|
||||
class="float-right"
|
||||
|
@ -144,7 +152,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator></q-separator>
|
||||
|
||||
<q-card-section>
|
||||
<q-input
|
||||
|
|
|
@ -481,27 +481,37 @@
|
|||
>{% endfor %}
|
||||
</q-card>
|
||||
{% endif %}
|
||||
<q-card v-if="chartConfig.showBalance">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletBalanceChart"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-card v-if="chartConfig.showBalanceInOut">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletBalanceInOut"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-card v-if="chartConfig.showPaymentCountInOut">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletPaymentsInOut"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<div
|
||||
v-show="chartDataPointCount"
|
||||
class="col-12 col-md-5 q-gutter-y-md"
|
||||
>
|
||||
<q-card v-if="chartConfig.showBalance">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletBalanceChart"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-card v-if="chartConfig.showBalanceInOut">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletBalanceInOut"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-card v-if="chartConfig.showPaymentCountInOut">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div style="height: 200px" class="q-pa-sm">
|
||||
<canvas ref="walletPaymentsInOut"></canvas>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
<div v-if="hasChartActive && !chartDataPointCount">
|
||||
<q-card>
|
||||
<q-card-section> No chart data available</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -8,52 +8,7 @@
|
|||
<q-card>
|
||||
<div class="q-pa-sm q-pl-lg">
|
||||
<div class="row items-center justify-between q-gutter-xs">
|
||||
<div class="col">
|
||||
<div class="float-left">
|
||||
<q-chip
|
||||
v-if="searchDate.timeFrom"
|
||||
removable
|
||||
@remove="removeCreatedFrom()"
|
||||
:label="searchDate.timeFrom"
|
||||
class="ellipsis"
|
||||
>
|
||||
</q-chip>
|
||||
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="searchDate.timeFrom" mask="YYYY-MM-DD">
|
||||
<div class="row">
|
||||
<q-btn
|
||||
label="Search"
|
||||
color="primary"
|
||||
flat
|
||||
@click="fetchPayments()"
|
||||
class="float-left"
|
||||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
<q-date v-model="searchDate.timeTo" mask="YYYY-MM-DD">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
<q-chip
|
||||
removable
|
||||
v-if="searchDate.timeTo"
|
||||
@remove="removeCreatedTo()"
|
||||
:label="searchDate.timeTo"
|
||||
class="ellipsis"
|
||||
>
|
||||
</q-chip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="float-left">
|
||||
<q-checkbox
|
||||
dense
|
||||
|
@ -115,7 +70,46 @@
|
|||
</q-checkbox>
|
||||
</div>
|
||||
<q-separator vertical class="q-ma-sm"></q-separator>
|
||||
|
||||
<q-btn icon="event" outline flat>
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="searchDate" mask="YYYY-MM-DD" range />
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<q-btn
|
||||
label="Search"
|
||||
@click="searchByDate()"
|
||||
color="primary"
|
||||
flat
|
||||
class="float-left"
|
||||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
@click="clearDateSeach()"
|
||||
label="Clear"
|
||||
class="float-right"
|
||||
color="grey"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-popup-proxy>
|
||||
<q-badge
|
||||
v-if="searchDate?.to || searchDate?.from"
|
||||
class="q-mt-lg q-mr-md"
|
||||
color="primary"
|
||||
rounded
|
||||
floating
|
||||
style="border-radius: 6px"
|
||||
/>
|
||||
</q-btn>
|
||||
<q-separator vertical class="q-ma-sm"></q-separator>
|
||||
<div>
|
||||
<q-btn
|
||||
v-if="g.user.admin"
|
||||
|
@ -214,7 +208,6 @@
|
|||
:columns="paymentsTable.columns"
|
||||
v-model:pagination="paymentsTable.pagination"
|
||||
:filter="paymentsTable.search"
|
||||
:loading="paymentsTable.loading"
|
||||
@request="fetchPayments"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
|
@ -272,8 +265,8 @@
|
|||
@click="showDetailsToggle(props.row)"
|
||||
v-if="props.row.status === 'success'"
|
||||
size="14px"
|
||||
:name="props.row.amount < 0 ? 'call_made' : 'call_received'"
|
||||
:color="props.row.amount < 0 ? 'pink' : 'green'"
|
||||
:name="props.row.outgoing ? 'call_made' : 'call_received'"
|
||||
:color="props.row.outgoing ? 'pink' : 'green'"
|
||||
class="cursor-pointer"
|
||||
></q-icon>
|
||||
<q-icon
|
||||
|
|
|
@ -4,10 +4,7 @@ window.PaymentsPageLogic = {
|
|||
return {
|
||||
payments: [],
|
||||
dailyChartData: [],
|
||||
searchDate: {
|
||||
timeFrom: null,
|
||||
timeTo: null
|
||||
},
|
||||
searchDate: {from: null, to: null},
|
||||
searchData: {
|
||||
wallet_id: null,
|
||||
payment_hash: null,
|
||||
|
@ -104,7 +101,7 @@ window.PaymentsPageLogic = {
|
|||
},
|
||||
search: null,
|
||||
hideEmpty: true,
|
||||
loading: true
|
||||
loading: false
|
||||
},
|
||||
chartsReady: false,
|
||||
showDetails: false,
|
||||
|
@ -116,10 +113,6 @@ window.PaymentsPageLogic = {
|
|||
this.chartsReady = true
|
||||
await this.$nextTick()
|
||||
this.initCharts()
|
||||
this.searchDate.timeFrom = moment()
|
||||
.subtract(1, 'month')
|
||||
.format('YYYY-MM-DD')
|
||||
this.searchDate.timeTo = moment().format('YYYY-MM-DD')
|
||||
await this.fetchPayments()
|
||||
},
|
||||
computed: {},
|
||||
|
@ -132,11 +125,11 @@ window.PaymentsPageLogic = {
|
|||
|
||||
delete filter['time[ge]']
|
||||
delete filter['time[le]']
|
||||
if (this.searchDate.timeFrom) {
|
||||
filter['time[ge]'] = this.searchDate.timeFrom + 'T00:00:00'
|
||||
if (this.searchDate.from) {
|
||||
filter['time[ge]'] = this.searchDate.from + 'T00:00:00'
|
||||
}
|
||||
if (this.searchDate.timeTo) {
|
||||
filter['time[le]'] = this.searchDate.timeTo + 'T23:59:59'
|
||||
if (this.searchDate.to) {
|
||||
filter['time[le]'] = this.searchDate.to + 'T23:59:59'
|
||||
}
|
||||
this.paymentsTable.filter = filter
|
||||
|
||||
|
@ -156,7 +149,7 @@ window.PaymentsPageLogic = {
|
|||
p.tag = p.extra.tag
|
||||
}
|
||||
p.timeFrom = moment(p.created_at).fromNow()
|
||||
|
||||
p.outgoing = p.amount < 0
|
||||
p.amount =
|
||||
new Intl.NumberFormat(window.LOCALE).format(p.amount / 1000) +
|
||||
' sats'
|
||||
|
@ -173,7 +166,6 @@ window.PaymentsPageLogic = {
|
|||
console.error(error)
|
||||
LNbits.utils.notifyApiError(error)
|
||||
} finally {
|
||||
this.paymentsTable.loading = false
|
||||
this.updateCharts(props)
|
||||
}
|
||||
},
|
||||
|
@ -183,15 +175,30 @@ window.PaymentsPageLogic = {
|
|||
}
|
||||
await this.fetchPayments()
|
||||
},
|
||||
clearDateSeach() {
|
||||
this.searchDate = {from: null, to: null}
|
||||
delete this.paymentsTable.filter['time[ge]']
|
||||
delete this.paymentsTable.filter['time[le]']
|
||||
this.fetchPayments()
|
||||
},
|
||||
searchByDate() {
|
||||
if (typeof this.searchDate === 'string') {
|
||||
this.searchDate = {
|
||||
from: this.searchDate,
|
||||
to: this.searchDate
|
||||
}
|
||||
}
|
||||
if (this.searchDate.from) {
|
||||
this.paymentsTable.filter['time[ge]'] =
|
||||
this.searchDate.from + 'T00:00:00'
|
||||
}
|
||||
if (this.searchDate.to) {
|
||||
this.paymentsTable.filter['time[le]'] = this.searchDate.to + 'T23:59:59'
|
||||
}
|
||||
|
||||
async removeCreatedFrom() {
|
||||
this.searchDate.timeFrom = null
|
||||
await this.fetchPayments()
|
||||
},
|
||||
async removeCreatedTo() {
|
||||
this.searchDate.timeTo = null
|
||||
await this.fetchPayments()
|
||||
this.fetchPayments()
|
||||
},
|
||||
|
||||
showDetailsToggle(payment) {
|
||||
this.paymentDetails = payment
|
||||
return (this.showDetails = !this.showDetails)
|
||||
|
@ -303,17 +310,17 @@ window.PaymentsPageLogic = {
|
|||
`/api/v1/payments/stats/daily?${noTimeParams}`
|
||||
)
|
||||
|
||||
const timeFrom = this.searchDate.timeFrom + 'T00:00:00'
|
||||
const timeTo = this.searchDate.timeTo + 'T00:00:00'
|
||||
const timeFrom = this.searchDate.from + 'T00:00:00'
|
||||
const timeTo = this.searchDate.to + 'T23:59:59'
|
||||
this.lnbitsBalance = data[data.length - 1].balance
|
||||
data = data.filter(p => {
|
||||
if (this.searchDate.timeFrom && this.searchDate.timeTo) {
|
||||
if (this.searchDate.from && this.searchDate.to) {
|
||||
return p.date >= timeFrom && p.date <= timeTo
|
||||
}
|
||||
if (this.searchDate.timeFrom) {
|
||||
if (this.searchDate.from) {
|
||||
return p.date >= timeFrom
|
||||
}
|
||||
if (this.searchDate.timeTo) {
|
||||
if (this.searchDate.to) {
|
||||
return p.date <= timeTo
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -116,6 +116,7 @@ window.WalletPageLogic = {
|
|||
primaryColor: this.$q.localStorage.getItem('lnbits.primaryColor'),
|
||||
secondaryColor: this.$q.localStorage.getItem('lnbits.secondaryColor'),
|
||||
chartData: [],
|
||||
chartDataPointCount: 0,
|
||||
chartConfig: {
|
||||
showBalance: true,
|
||||
showBalanceInOut: true,
|
||||
|
@ -151,6 +152,13 @@ window.WalletPageLogic = {
|
|||
},
|
||||
wallet() {
|
||||
return this.g.wallet
|
||||
},
|
||||
hasChartActive() {
|
||||
return (
|
||||
this.chartConfig.showBalance ||
|
||||
this.chartConfig.showBalanceInOut ||
|
||||
this.chartConfig.showPaymentCountInOut
|
||||
)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -824,11 +832,7 @@ window.WalletPageLogic = {
|
|||
this.chartConfig = {}
|
||||
return
|
||||
}
|
||||
if (
|
||||
!this.chartConfig.showBalance &&
|
||||
!this.chartConfig.showBalanceInOut &&
|
||||
!this.chartConfig.showPaymentCountInOut
|
||||
) {
|
||||
if (!this.hasChartActive) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -868,6 +872,7 @@ window.WalletPageLogic = {
|
|||
day: 'numeric'
|
||||
})
|
||||
)
|
||||
this.chartDataPointCount = data.length
|
||||
return {data, labels}
|
||||
},
|
||||
refreshCharts() {
|
||||
|
@ -964,12 +969,20 @@ window.WalletPageLogic = {
|
|||
{
|
||||
label: 'Balance In',
|
||||
borderRadius: 5,
|
||||
data: data.map(s => s.balance_in)
|
||||
data: data.map(s => s.balance_in),
|
||||
backgroundColor: LNbits.utils.hexAlpha(
|
||||
this.primaryColor,
|
||||
0.3
|
||||
)
|
||||
},
|
||||
{
|
||||
label: 'Balance Out',
|
||||
borderRadius: 5,
|
||||
data: data.map(s => s.balance_out)
|
||||
data: data.map(s => s.balance_out),
|
||||
backgroundColor: LNbits.utils.hexAlpha(
|
||||
this.secondaryColor,
|
||||
0.3
|
||||
)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1005,11 +1018,19 @@ window.WalletPageLogic = {
|
|||
datasets: [
|
||||
{
|
||||
label: 'Payments In',
|
||||
data: data.map(s => s.count_in)
|
||||
data: data.map(s => s.count_in),
|
||||
backgroundColor: LNbits.utils.hexAlpha(
|
||||
this.primaryColor,
|
||||
0.3
|
||||
)
|
||||
},
|
||||
{
|
||||
label: 'Payments Out',
|
||||
data: data.map(s => -s.count_out)
|
||||
data: data.map(s => -s.count_out),
|
||||
backgroundColor: LNbits.utils.hexAlpha(
|
||||
this.secondaryColor,
|
||||
0.3
|
||||
)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
<span>OFFLINE</span>
|
||||
</q-badge>
|
||||
<q-btn-dropdown
|
||||
v-if="g.user"
|
||||
v-if="g.user || isUserAuthorized"
|
||||
flat
|
||||
rounded
|
||||
size="sm"
|
||||
|
|
Loading…
Add table
Reference in a new issue