lnbits-legend/lnbits/static/js/users.js

463 lines
12 KiB
JavaScript
Raw Normal View History

window.app = Vue.createApp({
el: '#vue',
mixins: [window.windowMixin],
data: function () {
return {
2024-11-19 10:33:57 +02:00
paymentsWallet: {},
wallet: {},
cancel: {},
users: [],
wallets: [],
2024-11-19 10:33:57 +02:00
searchData: {
user: '',
username: '',
email: '',
pubkey: ''
},
paymentPage: {
show: false
},
2024-11-19 10:33:57 +02:00
activeWallet: {
userId: null,
show: false
},
topupDialog: {
show: false
},
2024-11-19 10:33:57 +02:00
activeUser: {
data: null,
showUserId: false,
show: false
},
2024-11-19 10:33:57 +02:00
createWalletDialog: {
data: {},
show: false
},
walletTable: {
columns: [
{
name: 'name',
align: 'left',
label: 'Name',
field: 'name'
},
2024-11-19 10:33:57 +02:00
{
name: 'id',
align: 'left',
label: 'Wallet Id',
field: 'id'
},
{
name: 'currency',
align: 'left',
label: 'Currency',
field: 'currency'
},
{
name: 'balance_msat',
align: 'left',
label: 'Balance',
field: 'balance_msat'
}
2024-11-19 10:33:57 +02:00
],
pagination: {
sortBy: 'name',
rowsPerPage: 10,
page: 1,
descending: true,
rowsNumber: 10
},
search: null,
hideEmpty: true,
loading: false
},
usersTable: {
columns: [
{
2024-11-19 10:33:57 +02:00
name: 'admin',
align: 'left',
2024-11-19 10:33:57 +02:00
label: 'Admin',
field: 'admin',
sortable: false
},
{
2024-11-19 10:33:57 +02:00
name: 'wallet_id',
align: 'left',
2024-11-19 10:33:57 +02:00
label: 'Wallets',
field: 'wallet_id',
sortable: false
},
{
2024-11-19 10:33:57 +02:00
name: 'user',
align: 'left',
2024-11-19 10:33:57 +02:00
label: 'User Id',
field: 'user',
sortable: false
},
2024-11-19 10:33:57 +02:00
{
name: 'username',
align: 'left',
label: 'Username',
field: 'username',
2024-11-19 10:33:57 +02:00
sortable: false
},
2024-11-19 10:33:57 +02:00
{
name: 'email',
align: 'left',
label: 'Email',
field: 'email',
2024-11-19 10:33:57 +02:00
sortable: false
},
{
name: 'pubkey',
align: 'left',
label: 'Public Key',
field: 'pubkey',
sortable: false
},
{
name: 'balance_msat',
align: 'left',
label: 'Balance',
field: 'balance_msat',
sortable: true
},
2024-11-19 10:33:57 +02:00
{
name: 'transaction_count',
align: 'left',
label: 'Payments',
field: 'transaction_count',
sortable: true
},
{
name: 'last_payment',
align: 'left',
label: 'Last Payment',
field: 'last_payment',
sortable: true
}
],
pagination: {
sortBy: 'balance_msat',
rowsPerPage: 10,
page: 1,
descending: true,
rowsNumber: 10
},
search: null,
hideEmpty: true,
loading: false
}
}
},
watch: {
'usersTable.hideEmpty': function (newVal, _) {
if (newVal) {
this.usersTable.filter = {
'transaction_count[gt]': 0
}
} else {
this.usersTable.filter = {}
}
this.fetchUsers()
}
},
created() {
this.fetchUsers()
},
2024-11-19 10:33:57 +02:00
methods: {
feat: parse nested pydantic models `fetchone` and `fetchall` + add shortcuts for insert_query and update_query into `Database` (#2714) * feat: add shortcuts for insert_query and update_query into `Database` example: await db.insert("table_name", base_model) * remove where from argument * chore: code clean-up * extension manager * lnbits-qrcode components * parse date from dict * refactor: make `settings` a fixture * chore: remove verbose key names * fix: time column * fix: cast balance to `int` * extension toggle vue3 * vue3 @input migration * fix: payment extra and payment hash * fix dynamic fields and ext db migration * remove shadow on cards in dark theme * screwed up and made more css pushes to this branch * attempt to make chip component in settings dynamic fields * dynamic chips * qrscanner * clean init admin settings * make get_user better * add dbversion model * remove update_payment_status/extra/details * traces for value and assertion errors * refactor services * add PaymentFiatAmount * return Payment on api endpoints * rename to get_user_from_account * refactor: just refactor (#2740) * rc5 * Fix db cache (#2741) * [refactor] split services.py (#2742) * refactor: spit `core.py` (#2743) * refactor: make QR more customizable * fix: print.html * fix: qrcode options * fix: white shadow on dark theme * fix: datetime wasnt parsed in dict_to_model * add timezone for conversion * only parse timestamp for sqlite, postgres does it * log internal payment success * fix: export wallet to phone QR * Adding a customisable border theme, like gradient (#2746) * fixed mobile scan btn * fix test websocket * fix get_payments tests * dict_to_model skip none values * preimage none instead of defaulting to 0000... * fixup test real invoice tests * fixed pheonixd for wss * fix nodemanager test settings * fix lnbits funding * only insert extension when they dont exist --------- Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com> Co-authored-by: Tiago Vasconcelos <talvasconcelos@gmail.com> Co-authored-by: Arc <ben@arc.wales> Co-authored-by: Arc <33088785+arcbtc@users.noreply.github.com>
2024-10-29 09:58:22 +01:00
formatDate: function (value) {
return LNbits.utils.formatDate(value)
},
formatSat: function (value) {
return LNbits.utils.formatSat(Math.floor(value / 1000))
},
2024-11-19 10:33:57 +02:00
backToUsersPage() {
this.activeUser.show = false
this.paymentPage.show = false
this.activeWallet.show = false
this.fetchUsers()
},
resetPassword(user_id) {
return LNbits.api
.request('PUT', `/users/api/v1/user/${user_id}/reset_password`)
.then(res => {
2024-11-19 10:33:57 +02:00
LNbits.utils
.confirmDialog(
'A reset key has been generated. Click OK to copy the rest key to your clipboard.'
)
.onOk(() => {
const url = window.location.origin + '?reset_key=' + res.data
this.copyText(url)
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createUser() {
LNbits.api
.request('POST', '/users/api/v1/user', null, this.activeUser.data)
.then(resp => {
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'User created!',
icon: null
})
2024-11-19 10:33:57 +02:00
this.activeUser.setPassword = true
this.activeUser.data = resp.data
this.fetchUsers()
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
2024-11-19 10:33:57 +02:00
updateUser() {
LNbits.api
2024-11-19 10:33:57 +02:00
.request(
'PUT',
`/users/api/v1/user/${this.activeUser.data.id}`,
null,
this.activeUser.data
)
.then(() => {
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'User updated!',
icon: null
})
2024-11-19 10:33:57 +02:00
this.activeUser.data = null
this.activeUser.show = false
this.fetchUsers()
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
2024-11-19 10:33:57 +02:00
createWallet() {
const userId = this.activeWallet.userId
if (!userId) {
Quasar.Notify.create({
type: 'warning',
message: 'No user selected!',
icon: null
})
return
}
LNbits.api
.request(
'POST',
2024-11-19 10:33:57 +02:00
`/users/api/v1/user/${userId}/wallet`,
null,
this.createWalletDialog.data
)
.then(() => {
2024-11-19 10:33:57 +02:00
this.fetchWallets(userId)
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'Wallet created!'
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteUser(user_id) {
LNbits.utils
.confirmDialog('Are you sure you want to delete this user?')
.onOk(() => {
LNbits.api
.request('DELETE', `/users/api/v1/user/${user_id}`)
.then(() => {
this.fetchUsers()
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'User deleted!',
icon: null
})
2024-11-19 10:33:57 +02:00
this.activeUser.data = null
this.activeUser.show = false
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
undeleteUserWallet(user_id, wallet) {
LNbits.api
.request(
2024-11-19 10:33:57 +02:00
'PUT',
`/users/api/v1/user/${user_id}/wallet/${wallet}/undelete`
)
.then(() => {
this.fetchWallets(user_id)
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'Undeleted user wallet!',
icon: null
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteUserWallet(user_id, wallet, deleted) {
const dialogText = deleted
? 'Wallet is already deleted, are you sure you want to permanently delete this user wallet?'
: 'Are you sure you want to delete this user wallet?'
LNbits.utils.confirmDialog(dialogText).onOk(() => {
LNbits.api
.request('DELETE', `/users/api/v1/user/${user_id}/wallet/${wallet}`)
.then(() => {
this.fetchWallets(user_id)
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'User wallet deleted!',
icon: null
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
2024-11-19 10:33:57 +02:00
copyWalletLink(walletId) {
const url = `${window.location.origin}/wallet?usr=${this.activeWallet.userId}&wal=${walletId}`
this.copyText(url)
},
2024-11-19 10:33:57 +02:00
fetchUsers(props) {
const params = LNbits.utils.prepareFilterQuery(this.usersTable, props)
LNbits.api
.request('GET', `/users/api/v1/user?${params}`)
.then(res => {
this.usersTable.loading = false
this.usersTable.pagination.rowsNumber = res.data.total
this.users = res.data.data
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
2024-11-19 10:33:57 +02:00
fetchWallets(userId) {
LNbits.api
2024-11-19 10:33:57 +02:00
.request('GET', `/users/api/v1/user/${userId}/wallet`)
.then(res => {
this.wallets = res.data
2024-11-19 10:33:57 +02:00
this.activeWallet.userId = userId
this.activeWallet.show = true
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
2024-11-19 10:33:57 +02:00
toggleAdmin(userId) {
LNbits.api
2024-11-19 10:33:57 +02:00
.request('GET', `/users/api/v1/user/${userId}/admin`)
.then(() => {
this.fetchUsers()
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: 'Toggled admin!',
icon: null
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
exportUsers() {
console.log('export users')
},
2024-11-19 10:33:57 +02:00
async showAccountPage(user_id) {
this.activeUser.showPassword = false
this.activeUser.showUserId = false
this.activeUser.setPassword = false
if (!user_id) {
this.activeUser.data = {extra: {}}
this.activeUser.show = true
return
}
try {
const {data} = await LNbits.api.request(
'GET',
`/users/api/v1/user/${user_id}`
)
this.activeUser.data = data
this.activeUser.show = true
} catch (error) {
console.warn(error)
Quasar.Notify.create({
type: 'warning',
message: 'Failed to get user!'
})
this.activeUser.show = false
}
},
showTopupDialog(walletId) {
this.wallet.id = walletId
this.topupDialog.show = true
},
showPayments(wallet_id) {
this.paymentsWallet = this.wallets.find(wallet => wallet.id === wallet_id)
this.paymentPage.show = true
},
topupCallback(res) {
if (res.success) {
this.wallets.forEach(wallet => {
if (res.wallet_id === wallet.id) {
wallet.balance_msat += res.credit * 1000
}
})
this.fetchUsers()
}
},
topupWallet() {
LNbits.api
.request(
'PUT',
'/users/api/v1/topup',
this.g.user.wallets[0].adminkey,
this.wallet
)
.then(_ => {
Quasar.Notify.create({
type: 'positive',
2024-11-19 10:33:57 +02:00
message: `Added ${this.wallet.amount} to ${this.wallet.id}`,
icon: null
})
this.wallet = {}
2024-11-19 10:33:57 +02:00
this.fetchWallets(this.activeWallet.userId)
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
2024-11-19 10:33:57 +02:00
},
searchUserBy(fieldName) {
const fieldValue = this.searchData[fieldName]
this.usersTable.filter = {}
if (fieldValue) {
this.usersTable.filter[fieldName] = fieldValue
}
this.fetchUsers()
},
shortify(value) {
valueLength = (value || '').length
if (valueLength <= 10) {
return value
}
return `${value.substring(0, 5)}...${value.substring(valueLength - 5, valueLength)}`
}
}
})