mirror of
https://github.com/lnbits/lnbits.git
synced 2025-03-26 17:51:53 +01:00
refactor: /wallet
tweaks
This commit is contained in:
parent
d03785558b
commit
649cc888ab
@ -158,12 +158,6 @@ new Vue({
|
||||
return (this.payments)
|
||||
? _.where(this.payments, {pending: 1}).length > 0
|
||||
: false;
|
||||
},
|
||||
paymentsFiltered: function () {
|
||||
return this.payments;
|
||||
return this.payments.filter(function (obj) {
|
||||
return obj.isPaid;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -325,6 +319,14 @@ new Vue({
|
||||
this.fetchPayments(true).then(function () {
|
||||
dismissMsg();
|
||||
});
|
||||
},
|
||||
exportCSV: function () {
|
||||
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'payments': function () {
|
||||
EventHub.$emit('update-wallet-balance', [this.w.wallet.id, this.balance]);
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
|
@ -57,10 +57,10 @@
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat
|
||||
color="deep-purple"
|
||||
color="grey"
|
||||
type="a" href="https://github.com/arcbtc/lnbits" target="_blank" rel="noopener">View project in GitHub</q-btn>
|
||||
<q-btn flat
|
||||
color="deep-purple"
|
||||
color="grey"
|
||||
type="a" href="https://paywall.link/to/f4e4e" target="_blank" rel="noopener">Donate</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
|
@ -54,7 +54,7 @@
|
||||
<h5 class="text-subtitle1 q-my-none">Transactions</h5>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat color="grey" onclick="exportbut()">Export to CSV</q-btn>
|
||||
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
|
||||
<!--<q-btn v-if="pendingPaymentsExist" dense flat round icon="update" color="grey" @click="checkPendingPayments">
|
||||
<q-tooltip>Check pending</q-tooltip>
|
||||
</q-btn>-->
|
||||
@ -64,7 +64,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<q-table dense flat
|
||||
:data="paymentsFiltered"
|
||||
:data="payments"
|
||||
row-key="payhash"
|
||||
:columns="paymentsTable.columns"
|
||||
:pagination.sync="paymentsTable.pagination">
|
||||
@ -122,40 +122,44 @@
|
||||
label="API info"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-expansion-item group="api" expand-separator label="Create an invoice">
|
||||
<q-expansion-item group="api" dense expand-separator label="Create an invoice (incoming)">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
Generate an invoice:<br /><code>POST /api/v1/invoices</code
|
||||
><br />Header
|
||||
<code><span class="text-light-green">POST</span> /api/v1/payments</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code
|
||||
>{"Grpc-Metadata-macaroon": "<i>{{ wallet.inkey }}</i
|
||||
>"}</code
|
||||
><br />
|
||||
Body <code>{"value": "200","memo": "beer"} </code><br />
|
||||
Returns
|
||||
<code>{"pay_req": string,"pay_id": string} </code><br />
|
||||
*payment will not register in the wallet until the "check
|
||||
invoice" endpoint is used<br /><br />
|
||||
|
||||
Check invoice:<br />
|
||||
Check an invoice:<br /><code
|
||||
>GET /api/v1/invoice/*payment_hash*</code
|
||||
><br />Header
|
||||
<code
|
||||
>{"Grpc-Metadata-macaroon": "<i>{{ wallet.inkey }}</i
|
||||
>"}</code
|
||||
><br />
|
||||
|
||||
Returns
|
||||
<code>{"PAID": "TRUE"}/{"PAID": "FALSE"} </code><br />
|
||||
*if using LNTXBOT return will hang until paid<br /><br />
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||
<code>{"out": false, "value": <int>, "memo": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
||||
<code>{"checking_id": <string>, "payment_request": <string>}</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" expand-separator label="Get an invoice">
|
||||
<q-expansion-item group="api" dense expand-separator label="Pay an invoice (outgoing)">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
This whole wallet will be deleted, the funds will be <strong>UNRECOVERABLE</strong>.
|
||||
<code><span class="text-light-green">POST</span> /api/v1/payments</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"Grpc-Metadata-macaroon": "{{ wallet.adminkey }}"}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||
<code>{"out": true, "bolt11": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 201 CREATED (application/json)</h5>
|
||||
<code>{"checking_id": <string>}</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" dense expand-separator label="Check an invoice (incoming or outgoing)"
|
||||
class="q-mb-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code><span class="text-light-blue">GET</span> /api/v1/payments/<checking_id></code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"Grpc-Metadata-macaroon": "{{ wallet.inkey }}"}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Returns 200 OK (application/json)</h5>
|
||||
<code>{"paid": <bool>}</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
|
@ -45,7 +45,7 @@ def api_payments_create_invoice():
|
||||
return jsonify({"checking_id": checking_id, "payment_request": payment_request}), Status.CREATED
|
||||
|
||||
|
||||
@api_check_wallet_macaroon(key_type="invoice")
|
||||
@api_check_wallet_macaroon(key_type="admin")
|
||||
@api_validate_post_request(required_params=["bolt11"])
|
||||
def api_payments_pay_invoice():
|
||||
if not isinstance(g.data["bolt11"], str) or not g.data["bolt11"].strip():
|
||||
|
@ -1,5 +1,7 @@
|
||||
var LOCALE = 'en'
|
||||
|
||||
var EventHub = new Vue();
|
||||
|
||||
var LNbits = {
|
||||
api: {
|
||||
request: function (method, url, macaroon, data) {
|
||||
@ -20,7 +22,7 @@ var LNbits = {
|
||||
});
|
||||
},
|
||||
payInvoice: function (wallet, bolt11) {
|
||||
return this.request('post', '/api/v1/payments', wallet.inkey, {
|
||||
return this.request('post', '/api/v1/payments', wallet.adminkey, {
|
||||
out: true,
|
||||
bolt11: bolt11
|
||||
});
|
||||
@ -53,7 +55,7 @@ var LNbits = {
|
||||
obj.wallets = obj.wallets.map(function (obj) {
|
||||
return mapWallet(obj);
|
||||
}).sort(function (a, b) {
|
||||
return a.name > b.name;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
return obj;
|
||||
},
|
||||
@ -94,6 +96,44 @@ var LNbits = {
|
||||
caption: [error.response.status, ' ', error.response.statusText].join('').toUpperCase() || null,
|
||||
icon: null
|
||||
});
|
||||
},
|
||||
exportCSV: function (columns, data) {
|
||||
var wrapCsvValue = function(val, formatFn) {
|
||||
var formatted = formatFn !== void 0
|
||||
? formatFn(val)
|
||||
: val;
|
||||
|
||||
formatted = (formatted === void 0 || formatted === null)
|
||||
? ''
|
||||
: String(formatted);
|
||||
|
||||
formatted = formatted.split('"').join('""');
|
||||
|
||||
return `"${formatted}"`;
|
||||
}
|
||||
|
||||
var content = [columns.map(function (col) {
|
||||
return wrapCsvValue(col.label);
|
||||
})].concat(data.map(function (row) {
|
||||
return columns.map(function (col) {
|
||||
return wrapCsvValue(
|
||||
(typeof col.field === 'function')
|
||||
? col.field(row)
|
||||
: row[(col.field === void 0) ? col.name : col.field],
|
||||
col.format
|
||||
);
|
||||
}).join(',');
|
||||
})).join('\r\n');
|
||||
|
||||
var status = Quasar.utils.exportFile('table-export.csv', content, 'text/csv');
|
||||
|
||||
if (status !== true) {
|
||||
Quasar.plugins.Notify.create({
|
||||
message: 'Browser denied file download...',
|
||||
color: 'negative',
|
||||
icon: null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -3,6 +3,7 @@ Vue.component('lnbits-wallet-list', {
|
||||
return {
|
||||
user: null,
|
||||
activeWallet: null,
|
||||
activeBalance: [],
|
||||
showForm: false,
|
||||
walletName: ''
|
||||
}
|
||||
@ -10,7 +11,7 @@ Vue.component('lnbits-wallet-list', {
|
||||
template: `
|
||||
<q-list v-if="user && user.wallets.length" dense class="lnbits-drawer__q-list">
|
||||
<q-item-label header>Wallets</q-item-label>
|
||||
<q-item v-for="wallet in user.wallets" :key="wallet.id"
|
||||
<q-item v-for="wallet in wallets" :key="wallet.id"
|
||||
clickable
|
||||
:active="activeWallet && activeWallet.id == wallet.id"
|
||||
tag="a" :href="wallet.url">
|
||||
@ -25,7 +26,7 @@ Vue.component('lnbits-wallet-list', {
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label lines="1">{{ wallet.name }}</q-item-label>
|
||||
<q-item-label caption>{{ wallet.fsat }} sat</q-item-label>
|
||||
<q-item-label caption>{{ wallet.live_fsat }} sat</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side v-show="activeWallet && activeWallet.id == wallet.id">
|
||||
<q-icon name="chevron_right" color="grey-5" size="md"></q-icon>
|
||||
@ -41,7 +42,7 @@ Vue.component('lnbits-wallet-list', {
|
||||
</q-item>
|
||||
<q-item v-if="showForm">
|
||||
<q-item-section>
|
||||
<q-form>
|
||||
<q-form @submit="createWallet">
|
||||
<q-input filled dense v-model="walletName" label="Name wallet *">
|
||||
<template v-slot:append>
|
||||
<q-btn round dense flat icon="send" size="sm" @click="createWallet" :disable="walletName == ''"></q-btn>
|
||||
@ -52,9 +53,23 @@ Vue.component('lnbits-wallet-list', {
|
||||
</q-item>
|
||||
</q-list>
|
||||
`,
|
||||
computed: {
|
||||
wallets: function () {
|
||||
var bal = this.activeBalance;
|
||||
return this.user.wallets.map(function (obj) {
|
||||
obj.live_fsat = (bal.length && bal[0] == obj.id)
|
||||
? LNbits.utils.formatSat(bal[1])
|
||||
: obj.fsat;
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createWallet: function () {
|
||||
LNbits.href.createWallet(this.walletName, this.user.id);
|
||||
},
|
||||
updateWalletBalance: function (payload) {
|
||||
this.activeBalance = payload;
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
@ -64,6 +79,7 @@ Vue.component('lnbits-wallet-list', {
|
||||
if (window.wallet) {
|
||||
this.activeWallet = LNbits.map.wallet(window.wallet);
|
||||
}
|
||||
EventHub.$on('update-wallet-balance', this.updateWalletBalance);
|
||||
}
|
||||
});
|
||||
|
||||
@ -113,8 +129,9 @@ Vue.component('lnbits-extension-list', {
|
||||
this.extensions = window.extensions.map(function (data) {
|
||||
return LNbits.map.extension(data);
|
||||
}).sort(function (a, b) {
|
||||
return a.name > b.name;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
if (window.user) {
|
||||
this.user = LNbits.map.user(window.user);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Quasar Framework v1.9.7
|
||||
* Quasar Framework v1.9.12
|
||||
* (c) 2015-present Razvan Stoenescu
|
||||
* Released under the MIT License.
|
||||
*/
|
1
lnbits/static/vendor/quasar@1.9.12/quasar.min.css
vendored
Normal file
1
lnbits/static/vendor/quasar@1.9.12/quasar.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
6
lnbits/static/vendor/quasar@1.9.12/quasar.umd.min.js
vendored
Normal file
6
lnbits/static/vendor/quasar@1.9.12/quasar.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* vuex v3.1.2
|
||||
* (c) 2019 Evan You
|
||||
* vuex v3.1.3
|
||||
* (c) 2020 Evan You
|
||||
* @license MIT
|
||||
*/
|
||||
(function (global, factory) {
|
||||
@ -398,7 +398,10 @@
|
||||
handler(payload);
|
||||
});
|
||||
});
|
||||
this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
|
||||
|
||||
this._subscribers
|
||||
.slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
|
||||
.forEach(function (sub) { return sub(mutation, this$1.state); });
|
||||
|
||||
if (
|
||||
options && options.silent
|
||||
@ -429,6 +432,7 @@
|
||||
|
||||
try {
|
||||
this._actionSubscribers
|
||||
.slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
|
||||
.filter(function (sub) { return sub.before; })
|
||||
.forEach(function (sub) { return sub.before(action, this$1.state); });
|
||||
} catch (e) {
|
||||
@ -797,9 +801,7 @@
|
||||
}
|
||||
|
||||
function getNestedState (state, path) {
|
||||
return path.length
|
||||
? path.reduce(function (state, key) { return state[key]; }, state)
|
||||
: state
|
||||
return path.reduce(function (state, key) { return state[key]; }, state)
|
||||
}
|
||||
|
||||
function unifyObjectStyle (type, payload, options) {
|
||||
@ -1042,7 +1044,7 @@
|
||||
var index = {
|
||||
Store: Store,
|
||||
install: install,
|
||||
version: '3.1.2',
|
||||
version: '3.1.3',
|
||||
mapState: mapState,
|
||||
mapMutations: mapMutations,
|
||||
mapGetters: mapGetters,
|
File diff suppressed because one or more lines are too long
@ -3,7 +3,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Material+Icons" type="text/css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='vendor/quasar@1.9.7/quasar.min.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='vendor/quasar@1.9.12/quasar.min.css') }}">
|
||||
{% assets 'base_css' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
|
||||
{% endassets %}
|
||||
@ -62,15 +62,15 @@
|
||||
{% if DEBUG %}
|
||||
<script src="{{ url_for('static', filename='vendor/vue@2.6.11/vue.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='vendor/vue-router@3.1.6/vue-router.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='vendor/vuex@3.1.2/vuex.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='vendor/quasar@1.9.7/quasar.umd.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='vendor/vuex@3.1.3/vuex.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='vendor/quasar@1.9.12/quasar.umd.js') }}"></script>
|
||||
{% else %}
|
||||
{% assets output='__bundle__/vue.js',
|
||||
'vendor/quasar@1.9.7/quasar.ie.polyfills.umd.min.js',
|
||||
'vendor/quasar@1.9.12/quasar.ie.polyfills.umd.min.js',
|
||||
'vendor/vue@2.6.11/vue.min.js',
|
||||
'vendor/vue-router@3.1.6/vue-router.min.js',
|
||||
'vendor/vuex@3.1.2/vuex.min.js',
|
||||
'vendor/quasar@1.9.7/quasar.umd.min.js' %}
|
||||
'vendor/vuex@3.1.3/vuex.min.js',
|
||||
'vendor/quasar@1.9.12/quasar.umd.min.js' %}
|
||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
{% endif %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user