refactor: move /node into vue component (#3460)
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
@@ -656,3 +656,261 @@ window.app.component('separator-text', {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-ranks', {
|
||||
props: ['ranks'],
|
||||
data() {
|
||||
return {
|
||||
stats: [
|
||||
{label: 'Capacity', key: 'capacity'},
|
||||
{label: 'Channels', key: 'channelcount'},
|
||||
{label: 'Age', key: 'age'},
|
||||
{label: 'Growth', key: 'growth'},
|
||||
{label: 'Availability', key: 'availability'}
|
||||
]
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card class='q-my-none'>
|
||||
<div class='column q-ma-md'>
|
||||
<h5 class='text-subtitle1 text-bold q-my-none'>1ml Node Rank</h5>
|
||||
<div v-for='stat in stats' class='q-gutter-sm'>
|
||||
<div class='row items-center'>
|
||||
<div class='col-9'>{{ stat.label }}</div>
|
||||
<div class='col-3 text-subtitle1 text-bold'>
|
||||
{{ (ranks && ranks[stat.key]) ?? '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-stats', {
|
||||
props: ['stats'],
|
||||
data() {
|
||||
return {
|
||||
states: [
|
||||
{label: 'Active', value: 'active', color: 'green'},
|
||||
{label: 'Pending', value: 'pending', color: 'orange'},
|
||||
{label: 'Inactive', value: 'inactive', color: 'grey'},
|
||||
{label: 'Closed', value: 'closed', color: 'red'}
|
||||
]
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<div class='column q-ma-md'>
|
||||
<h5 class='text-subtitle1 text-bold q-my-none'>Channels</h5>
|
||||
<div v-for='state in states' class='q-gutter-sm'>
|
||||
<div class='row'>
|
||||
<div class='col-9'>
|
||||
<q-badge rounded size='md' :color='state.color'>{{ state.label }}</q-badge>
|
||||
</div>
|
||||
<div class='col-3 text-subtitle1 text-bold'>
|
||||
{{ (stats?.counts && stats.counts[state.value]) ?? "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value() {
|
||||
return (
|
||||
this.amount ??
|
||||
(this.btc
|
||||
? LNbits.utils.formatSat(this.btc)
|
||||
: LNbits.utils.formatMsat(this.msat))
|
||||
)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class='text-overline text-primary'>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
<span class='text-h4 text-bold q-my-none'>{{ value }}</span>
|
||||
<span class='text-h5' v-if='msat != undefined'>sats</span>
|
||||
<span class='text-h5' v-if='btc != undefined'>BTC</span>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-qrcode', {
|
||||
props: ['info'],
|
||||
mixins: [window.windowMixin],
|
||||
template: `
|
||||
<q-card class="my-card">
|
||||
<q-card-section>
|
||||
<div class="text-h6">
|
||||
<div style="text-align: center">
|
||||
<vue-qrcode
|
||||
:value="info.addresses[0]"
|
||||
:options="{width: 250}"
|
||||
v-if='info.addresses[0]'
|
||||
class="rounded-borders"
|
||||
></vue-qrcode>
|
||||
<div v-else class='text-subtitle1'>
|
||||
No addresses available
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions vertical>
|
||||
<q-btn
|
||||
dense
|
||||
unelevated
|
||||
size="md"
|
||||
@click="copyText(info.id)"
|
||||
>Public Key<q-tooltip> Click to copy </q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-balance', {
|
||||
props: ['balance', 'color'],
|
||||
methods: {
|
||||
formatMsat(msat) {
|
||||
return LNbits.utils.formatMsat(msat)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="row items-center justify-between">
|
||||
<span class="text-weight-thin">
|
||||
Local: {{ formatMsat(balance.local_msat) }}
|
||||
sats
|
||||
</span>
|
||||
<span class="text-weight-thin">
|
||||
Remote: {{ formatMsat(balance.remote_msat) }}
|
||||
sats
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<q-linear-progress
|
||||
rounded
|
||||
size="25px"
|
||||
:value="balance.local_msat / balance.total_msat"
|
||||
:color="color"
|
||||
:style="\`color: #\${this.color}\`"
|
||||
>
|
||||
<div class="absolute-full flex flex-center">
|
||||
<q-badge
|
||||
color="white"
|
||||
text-color="accent"
|
||||
:label="formatMsat(balance.total_msat) + ' sats'"
|
||||
>
|
||||
{{ balance.alias }}
|
||||
</q-badge>
|
||||
</div>
|
||||
</q-linear-progress>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-date', {
|
||||
props: ['ts'],
|
||||
computed: {
|
||||
date() {
|
||||
return LNbits.utils.formatDate(this.ts)
|
||||
},
|
||||
dateFrom() {
|
||||
return moment.utc(this.date).local().fromNow()
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<q-tooltip>{{ this.date }}</q-tooltip>
|
||||
{{ this.dateFrom }}
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-info', {
|
||||
props: ['info'],
|
||||
data() {
|
||||
return {
|
||||
showDialog: false
|
||||
}
|
||||
},
|
||||
mixins: [window.windowMixin],
|
||||
methods: {
|
||||
shortenNodeId(nodeId) {
|
||||
return nodeId
|
||||
? nodeId.substring(0, 5) + '...' + nodeId.substring(nodeId.length - 5)
|
||||
: '...'
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class='row items-baseline q-gutter-x-sm'>
|
||||
<div class='text-h4 text-bold'>{{ this.info.alias }}</div>
|
||||
<div class='row items-center q-gutter-sm'>
|
||||
<div class='text-subtitle1 text-light'>{{ this.info.backend_name }}</div>
|
||||
<q-badge
|
||||
:style='\`background-color: #\${this.info.color}\`'
|
||||
class='text-bold'
|
||||
>
|
||||
#{{ this.info.color }}
|
||||
</q-badge>
|
||||
<div class='text-bold'>{{ shortenNodeId(this.info.id) }}</div>
|
||||
<q-btn
|
||||
size='xs'
|
||||
flat
|
||||
dense
|
||||
icon='content_paste'
|
||||
@click='copyText(info.id)'
|
||||
></q-btn>
|
||||
<q-btn
|
||||
size='xs'
|
||||
flat
|
||||
dense
|
||||
icon='qr_code'
|
||||
@click='showDialog = true'
|
||||
></q-btn>
|
||||
</div>
|
||||
<q-dialog v-model="showDialog">
|
||||
<lnbits-node-qrcode :info='info'></lnbits-node-qrcode>
|
||||
</q-dialog>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value() {
|
||||
return (
|
||||
this.amount ??
|
||||
(this.btc
|
||||
? LNbits.utils.formatSat(this.btc)
|
||||
: LNbits.utils.formatMsat(this.msat))
|
||||
)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class='text-overline text-primary'>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
<span class='text-h4 text-bold q-my-none'>{{ value }}</span>
|
||||
<span class='text-h5' v-if='msat != undefined'>sats</span>
|
||||
<span class='text-h5' v-if='btc != undefined'>BTC</span>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
@@ -205,16 +205,12 @@ const routes = [
|
||||
{
|
||||
path: '/node',
|
||||
name: 'Node',
|
||||
component: DynamicComponent,
|
||||
props: {
|
||||
fetchUrl: '/node',
|
||||
scripts: ['/static/js/node.js']
|
||||
}
|
||||
component: PageNode
|
||||
},
|
||||
{
|
||||
path: '/node',
|
||||
name: 'Node',
|
||||
component: DynamicComponent
|
||||
path: '/node/public',
|
||||
name: 'NodePublic',
|
||||
component: PageNodePublic
|
||||
},
|
||||
{
|
||||
path: '/payments',
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
window.PageNodePublic = {
|
||||
template: '#page-node-public',
|
||||
mixins: [window.windowMixin],
|
||||
data() {
|
||||
return {
|
||||
enabled: false,
|
||||
isSuperUser: false,
|
||||
wallet: {},
|
||||
tab: 'dashboard',
|
||||
payments: 1000,
|
||||
info: {},
|
||||
channel_stats: {},
|
||||
channels: [],
|
||||
activeBalance: {},
|
||||
ranks: {},
|
||||
peers: [],
|
||||
connectPeerDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
},
|
||||
openChannelDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
},
|
||||
closeChannelDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
},
|
||||
nodeInfoDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
},
|
||||
states: [
|
||||
{label: 'Active', value: 'active', color: 'green'},
|
||||
{label: 'Pending', value: 'pending', color: 'orange'},
|
||||
{label: 'Inactive', value: 'inactive', color: 'grey'},
|
||||
{label: 'Closed', value: 'closed', color: 'red'}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getInfo()
|
||||
this.get1MLStats()
|
||||
},
|
||||
methods: {
|
||||
formatMsat(msat) {
|
||||
return LNbits.utils.formatMsat(msat)
|
||||
},
|
||||
api(method, url, data) {
|
||||
return LNbits.api.request(method, '/node/public/api/v1' + url, {}, data)
|
||||
},
|
||||
getInfo() {
|
||||
this.api('GET', '/info', {})
|
||||
.then(response => {
|
||||
this.info = response.data
|
||||
this.channel_stats = response.data.channel_stats
|
||||
this.enabled = true
|
||||
})
|
||||
.catch(() => {
|
||||
this.info = {}
|
||||
this.channel_stats = {}
|
||||
})
|
||||
},
|
||||
get1MLStats() {
|
||||
this.api('GET', '/rank', {})
|
||||
.then(response => {
|
||||
this.ranks = response.data
|
||||
})
|
||||
.catch(() => {
|
||||
this.ranks = {}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
window.NodePageLogic = {
|
||||
window.PageNode = {
|
||||
mixins: [window.windowMixin],
|
||||
template: '#page-node',
|
||||
config: {
|
||||
globalProperties: {
|
||||
LNbits,
|
||||
@@ -225,15 +226,24 @@ window.NodePageLogic = {
|
||||
})
|
||||
},
|
||||
getInfo() {
|
||||
return this.api('GET', '/info').then(response => {
|
||||
this.info = response.data
|
||||
this.channel_stats = response.data.channel_stats
|
||||
})
|
||||
return this.api('GET', '/info')
|
||||
.then(response => {
|
||||
this.info = response.data
|
||||
this.channel_stats = response.data.channel_stats
|
||||
})
|
||||
.catch(() => {
|
||||
this.info = {}
|
||||
this.channel_stats = {}
|
||||
})
|
||||
},
|
||||
get1MLStats() {
|
||||
return this.api('GET', '/rank').then(response => {
|
||||
this.ranks = response.data
|
||||
})
|
||||
return this.api('GET', '/rank')
|
||||
.then(response => {
|
||||
this.ranks = response.data
|
||||
})
|
||||
.catch(() => {
|
||||
this.ranks = {}
|
||||
})
|
||||
},
|
||||
getPayments(props) {
|
||||
if (props) {
|
||||
@@ -266,7 +276,6 @@ window.NodePageLogic = {
|
||||
getPeers() {
|
||||
return this.api('GET', '/peers').then(response => {
|
||||
this.peers.data = response.data
|
||||
console.log('peers', this.peers)
|
||||
})
|
||||
},
|
||||
connectPeer() {
|
||||
@@ -343,7 +352,6 @@ window.NodePageLogic = {
|
||||
showTransactionDetailsDialog(details) {
|
||||
this.transactionDetailsDialog.show = true
|
||||
this.transactionDetailsDialog.data = details
|
||||
console.log('details', details)
|
||||
},
|
||||
shortenNodeId(nodeId) {
|
||||
return nodeId
|
||||
@@ -352,261 +360,3 @@ window.NodePageLogic = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.app.component('lnbits-node-ranks', {
|
||||
props: ['ranks'],
|
||||
data() {
|
||||
return {
|
||||
stats: [
|
||||
{label: 'Capacity', key: 'capacity'},
|
||||
{label: 'Channels', key: 'channelcount'},
|
||||
{label: 'Age', key: 'age'},
|
||||
{label: 'Growth', key: 'growth'},
|
||||
{label: 'Availability', key: 'availability'}
|
||||
]
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card class='q-my-none'>
|
||||
<div class='column q-ma-md'>
|
||||
<h5 class='text-subtitle1 text-bold q-my-none'>1ml Node Rank</h5>
|
||||
<div v-for='stat in stats' class='q-gutter-sm'>
|
||||
<div class='row items-center'>
|
||||
<div class='col-9'>{{ stat.label }}</div>
|
||||
<div class='col-3 text-subtitle1 text-bold'>
|
||||
{{ (ranks && ranks[stat.key]) ?? '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-stats', {
|
||||
props: ['stats'],
|
||||
data() {
|
||||
return {
|
||||
states: [
|
||||
{label: 'Active', value: 'active', color: 'green'},
|
||||
{label: 'Pending', value: 'pending', color: 'orange'},
|
||||
{label: 'Inactive', value: 'inactive', color: 'grey'},
|
||||
{label: 'Closed', value: 'closed', color: 'red'}
|
||||
]
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<div class='column q-ma-md'>
|
||||
<h5 class='text-subtitle1 text-bold q-my-none'>Channels</h5>
|
||||
<div v-for='state in states' class='q-gutter-sm'>
|
||||
<div class='row'>
|
||||
<div class='col-9'>
|
||||
<q-badge rounded size='md' :color='state.color'>{{ state.label }}</q-badge>
|
||||
</div>
|
||||
<div class='col-3 text-subtitle1 text-bold'>
|
||||
{{ (stats?.counts && stats.counts[state.value]) ?? "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value() {
|
||||
return (
|
||||
this.amount ??
|
||||
(this.btc
|
||||
? LNbits.utils.formatSat(this.btc)
|
||||
: LNbits.utils.formatMsat(this.msat))
|
||||
)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class='text-overline text-primary'>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
<span class='text-h4 text-bold q-my-none'>{{ value }}</span>
|
||||
<span class='text-h5' v-if='msat != undefined'>sats</span>
|
||||
<span class='text-h5' v-if='btc != undefined'>BTC</span>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-qrcode', {
|
||||
props: ['info'],
|
||||
mixins: [window.windowMixin],
|
||||
template: `
|
||||
<q-card class="my-card">
|
||||
<q-card-section>
|
||||
<div class="text-h6">
|
||||
<div style="text-align: center">
|
||||
<vue-qrcode
|
||||
:value="info.addresses[0]"
|
||||
:options="{width: 250}"
|
||||
v-if='info.addresses[0]'
|
||||
class="rounded-borders"
|
||||
></vue-qrcode>
|
||||
<div v-else class='text-subtitle1'>
|
||||
No addresses available
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions vertical>
|
||||
<q-btn
|
||||
dense
|
||||
unelevated
|
||||
size="md"
|
||||
@click="copyText(info.id)"
|
||||
>Public Key<q-tooltip> Click to copy </q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-info', {
|
||||
props: ['info'],
|
||||
data() {
|
||||
return {
|
||||
showDialog: false
|
||||
}
|
||||
},
|
||||
mixins: [window.windowMixin],
|
||||
methods: {
|
||||
shortenNodeId(nodeId) {
|
||||
return nodeId
|
||||
? nodeId.substring(0, 5) + '...' + nodeId.substring(nodeId.length - 5)
|
||||
: '...'
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class='row items-baseline q-gutter-x-sm'>
|
||||
<div class='text-h4 text-bold'>{{ this.info.alias }}</div>
|
||||
<div class='row items-center q-gutter-sm'>
|
||||
<div class='text-subtitle1 text-light'>{{ this.info.backend_name }}</div>
|
||||
<q-badge
|
||||
:style='\`background-color: #\${this.info.color}\`'
|
||||
class='text-bold'
|
||||
>
|
||||
#{{ this.info.color }}
|
||||
</q-badge>
|
||||
<div class='text-bold'>{{ shortenNodeId(this.info.id) }}</div>
|
||||
<q-btn
|
||||
size='xs'
|
||||
flat
|
||||
dense
|
||||
icon='content_paste'
|
||||
@click='copyText(info.id)'
|
||||
></q-btn>
|
||||
<q-btn
|
||||
size='xs'
|
||||
flat
|
||||
dense
|
||||
icon='qr_code'
|
||||
@click='showDialog = true'
|
||||
></q-btn>
|
||||
</div>
|
||||
<q-dialog v-model="showDialog">
|
||||
<lnbits-node-qrcode :info='info'></lnbits-node-qrcode>
|
||||
</q-dialog>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value() {
|
||||
return (
|
||||
this.amount ??
|
||||
(this.btc
|
||||
? LNbits.utils.formatSat(this.btc)
|
||||
: LNbits.utils.formatMsat(this.msat))
|
||||
)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class='text-overline text-primary'>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
<span class='text-h4 text-bold q-my-none'>{{ value }}</span>
|
||||
<span class='text-h5' v-if='msat != undefined'>sats</span>
|
||||
<span class='text-h5' v-if='btc != undefined'>BTC</span>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-balance', {
|
||||
props: ['balance', 'color'],
|
||||
methods: {
|
||||
formatMsat(msat) {
|
||||
return LNbits.utils.formatMsat(msat)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="row items-center justify-between">
|
||||
<span class="text-weight-thin">
|
||||
Local: {{ formatMsat(balance.local_msat) }}
|
||||
sats
|
||||
</span>
|
||||
<span class="text-weight-thin">
|
||||
Remote: {{ formatMsat(balance.remote_msat) }}
|
||||
sats
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<q-linear-progress
|
||||
rounded
|
||||
size="25px"
|
||||
:value="balance.local_msat / balance.total_msat"
|
||||
:color="color"
|
||||
:style="\`color: #\${this.color}\`"
|
||||
>
|
||||
<div class="absolute-full flex flex-center">
|
||||
<q-badge
|
||||
color="white"
|
||||
text-color="accent"
|
||||
:label="formatMsat(balance.total_msat) + ' sats'"
|
||||
>
|
||||
{{ balance.alias }}
|
||||
</q-badge>
|
||||
</div>
|
||||
</q-linear-progress>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-date', {
|
||||
props: ['ts'],
|
||||
computed: {
|
||||
date() {
|
||||
return LNbits.utils.formatDate(this.ts)
|
||||
},
|
||||
dateFrom() {
|
||||
return moment.utc(this.date).local().fromNow()
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<q-tooltip>{{ this.date }}</q-tooltip>
|
||||
{{ this.dateFrom }}
|
||||
</div>
|
||||
`
|
||||
})
|
||||
@@ -44,6 +44,8 @@
|
||||
],
|
||||
"components": [
|
||||
"js/pages/payments.js",
|
||||
"js/pages/node.js",
|
||||
"js/pages/node-public.js",
|
||||
"js/components/lnbits-qrcode.js",
|
||||
"js/components/lnbits-qrcode-lnurl.js",
|
||||
"js/components/lnbits-funding-sources.js",
|
||||
|
||||
Reference in New Issue
Block a user