refactor: move _wallet-share.html to vue component (#3522)

This commit is contained in:
dni ⚡ 2025-11-13 15:48:46 +01:00 committed by GitHub
parent 1463d75ee2
commit ff7f5c1ca5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 361 additions and 342 deletions

View file

@ -1,251 +0,0 @@
<q-expansion-item
v-if="wallet.walletType == 'lightning'"
group="extras"
icon="share"
:label="$t('share_wallet')"
>
<template v-slot:header>
<q-item-section avatar>
<q-avatar icon="share" style="margin-left: -5px" />
</q-item-section>
<q-item-section>
<span v-text="$t('share_wallet')"></span>
</q-item-section>
<q-item-section side v-if="walletPendingRequests.length">
<div class="row items-center">
<q-icon name="hail" color="secondary" size="24px" />
<span v-text="walletPendingRequests.length"></span>
</div>
</q-item-section>
</template>
<q-card>
<q-card-section>
You can invite other users to have access to this wallet.
<br />
The access is limitted by the permission you grant.
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-5">
<q-input
v-model="walletShareInvite.username"
@keyup.enter="inviteUserToWallet()"
label="Username"
hint="Invite user to this wallet"
dense
>
</q-input>
</div>
<div class="col-6">
<q-select
:options="permissionOptions"
v-model="walletShareInvite.permissions"
emit-value
map-options
multiple
use-chips
dense
class="q-pl-md"
hint="Select permissions for this user"
></q-select>
</div>
<div class="col-1">
<q-btn
@click="inviteUserToWallet()"
dense
flat
icon="person_add_alt"
class="float-right"
></q-btn>
</div>
</div>
</q-card-section>
<q-separator class="q-mt-lg"></q-separator>
<q-expansion-item
group="wallet_shares"
dense
expand-separator
icon="share"
:label="'Shared With (' + walletApprovedShares.length + ')'"
>
<q-card>
<q-card-section v-if="walletApprovedShares.length">
<div v-for="share in walletApprovedShares" class="row q-mb-xs">
<div class="col-3 q-mt-md">
<strong v-text="share.username"></strong>
</div>
<div class="col-1 q-mt-sm">
<q-icon v-if="share.comment" name="add_comment">
<q-tooltip v-text="share.comment"></q-tooltip>
</q-icon>
</div>
<div class="col-6">
<q-select
v-model="share.permissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
></q-select>
</div>
<div class="col-1 q-mt-sm">
<q-btn
flat
color="red"
icon="delete"
outline
class="full-width"
@click="deleteSharePermission(share)"
></q-btn>
</div>
<div class="col-1 q-mt-sm">
<q-btn
dense
flat
color="primary"
icon="check"
class="full-width"
@click="updateSharePermissions(share)"
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section v-else>
<span>This wallet is not shared with anyone.</span>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
group="wallet_shares"
dense
expand-separator
icon="group_add"
:label="'Pending Invitations (' + walletPendingInvites.length + ')'"
>
<q-card>
<q-card-section v-if="walletPendingInvites.length">
<div v-for="share in walletPendingInvites" class="row q-mb-xs">
<div class="col-3 q-mt-md">
<strong v-text="share.username"></strong>
</div>
<div class="col-8">
<q-select
v-model="share.permissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
></q-select>
</div>
<div class="col-1 q-mt-sm">
<q-btn
flat
color="red"
icon="delete"
outline
class="full-width"
@click="deleteSharePermission(share)"
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section v-else>
<span>No pending invites.</span>
</q-card-section>
</q-card>
</q-expansion-item>
<q-card-section> </q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
v-else-if="wallet.walletType == 'lightning-shared'"
group="extras"
icon="supervisor_account"
:label="$t('shared_wallet')"
>
<q-card>
<q-card-section>
This wallet does not belong to you. It is a shared Lightning wallet.
<br />
The owner can revoke the permissions at any moment.
</q-card-section>
<q-card-section>
<q-item dense class="q-pa-none">
<q-item-section>
<q-item-label>
<strong>Shared Wallet ID: </strong
><em
v-text="walletIdHidden ? '****************' : wallet.sharedWalletId"
></em>
</q-item-label>
</q-item-section>
<q-item-section side>
<div>
<q-icon
:name="walletIdHidden ? 'visibility_off' : 'visibility'"
class="cursor-pointer"
@click="walletIdHidden = !walletIdHidden"
></q-icon>
<q-icon
name="content_copy"
class="cursor-pointer q-ml-sm"
@click="copyText(wallet.sharedWalletId)"
></q-icon>
<q-icon name="qr_code" class="cursor-pointer q-ml-sm">
<q-popup-proxy>
<div class="q-pa-md">
<lnbits-qrcode
:value="wallet.sharedWalletId"
:show-buttons="false"
></lnbits-qrcode>
</div>
</q-popup-proxy>
</q-icon>
</div>
</q-item-section>
</q-item>
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-3 q-mt-md">
<strong>Permissions:</strong>
</div>
<div class="col-9">
<q-select
v-model="wallet.sharePermissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
disable
></q-select>
</div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
v-else
group="extras"
icon="question_mark"
:label="$t('share_wallet')"
>
<q-card>
<q-card-section>
Unknown wallet type:
<strong v-text="wallet.walletType" class="q-ml-md"></strong>
</q-card-section>
</q-card>
</q-expansion-item>

View file

@ -341,7 +341,7 @@
</q-card>
</q-expansion-item>
<q-separator></q-separator>
{% include "core/_wallet_share.html" %}
<lnbits-wallet-share></lnbits-wallet-share>
<q-separator></q-separator>
<q-expansion-item
group="extras"

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,99 @@
window.app.component('lnbits-wallet-share', {
template: '#lnbits-wallet-share',
mixins: [window.windowMixin],
computed: {
walletApprovedShares() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'approved'
)
},
walletPendingRequests() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'request_access'
)
},
walletPendingInvites() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'invite_sent'
)
}
},
data() {
return {
permissionOptions: [
{label: 'View', value: 'view-payments'},
{label: 'Receive', value: 'receive-payments'},
{label: 'Send', value: 'send-payments'}
],
walletShareInvite: {
unsername: '',
permissions: []
}
}
},
methods: {
async updateSharePermissions(permission) {
try {
const {data} = await LNbits.api.request(
'PUT',
'/api/v1/wallet/share',
this.g.wallet.adminkey,
permission
)
Object.assign(permission, data)
Quasar.Notify.create({
message: 'Wallet permission updated.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
},
async inviteUserToWallet() {
try {
const {data} = await LNbits.api.request(
'PUT',
'/api/v1/wallet/share/invite',
this.g.wallet.adminkey,
{
...this.walletShareInvite,
status: 'invite_sent',
wallet_id: this.g.wallet.id
}
)
this.g.wallet.extra.shared_with.push(data)
this.walletShareInvite = {username: '', permissions: []}
Quasar.Notify.create({
message: 'User invited to wallet.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
},
deleteSharePermission(permission) {
LNbits.utils
.confirmDialog('Are you sure you want to remove this share permission?')
.onOk(async () => {
try {
await LNbits.api.request(
'DELETE',
`/api/v1/wallet/share/${permission.request_id}`,
this.g.wallet.adminkey
)
this.g.wallet.extra.shared_with =
this.g.wallet.extra.shared_with.filter(
value => value.wallet_id !== permission.wallet_id
)
Quasar.Notify.create({
message: 'Wallet permission deleted.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
})
}
}
})

View file

@ -125,16 +125,7 @@ window.WalletPageLogic = {
showBalanceInOut: true,
showPaymentCountInOut: true
},
paymentsFilter: {},
permissionOptions: [
{label: 'View', value: 'view-payments'},
{label: 'Receive', value: 'receive-payments'},
{label: 'Send', value: 'send-payments'}
],
walletShareInvite: {
unsername: '',
permissions: []
}
paymentsFilter: {}
}
},
computed: {
@ -177,21 +168,6 @@ window.WalletPageLogic = {
wallet() {
return this.g.wallet
},
walletApprovedShares() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'approved'
)
},
walletPendingRequests() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'request_access'
)
},
walletPendingInvites() {
return this.g.wallet.extra.shared_with.filter(
s => s.status === 'invite_sent'
)
},
hasChartActive() {
return (
this.chartConfig.showBalance ||
@ -665,69 +641,6 @@ window.WalletPageLogic = {
LNbits.utils.notifyApiError(err)
})
},
async updateSharePermissions(permission) {
try {
const {data} = await LNbits.api.request(
'PUT',
'/api/v1/wallet/share',
this.g.wallet.adminkey,
permission
)
Object.assign(permission, data)
Quasar.Notify.create({
message: 'Wallet permission updated.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
},
async inviteUserToWallet() {
try {
const {data} = await LNbits.api.request(
'PUT',
'/api/v1/wallet/share/invite',
this.g.wallet.adminkey,
{
...this.walletShareInvite,
status: 'invite_sent',
wallet_id: this.g.wallet.id
}
)
this.g.wallet.extra.shared_with.push(data)
this.walletShareInvite = {username: '', permissions: []}
Quasar.Notify.create({
message: 'User invited to wallet.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
},
deleteSharePermission(permission) {
LNbits.utils
.confirmDialog('Are you sure you want to remove this share permission?')
.onOk(async () => {
try {
await LNbits.api.request(
'DELETE',
`/api/v1/wallet/share/${permission.request_id}`,
this.g.wallet.adminkey
)
this.g.wallet.extra.shared_with =
this.g.wallet.extra.shared_with.filter(
value => value.wallet_id !== permission.wallet_id
)
Quasar.Notify.create({
message: 'Wallet permission deleted.',
type: 'positive'
})
} catch (err) {
LNbits.utils.notifyApiError(err)
}
})
},
deleteWallet() {
LNbits.utils
.confirmDialog('Are you sure you want to delete this wallet?')

View file

@ -69,6 +69,7 @@
"js/components/admin/lnbits-admin-audit.js",
"js/components/lnbits-wallet-list.js",
"js/components/lnbits-wallet-api-docs.js",
"js/components/lnbits-wallet-share.js",
"js/components/lnbits-home-logos.js",
"js/components/lnbits-new-user-wallet.js",
"js/components/lnbits-qrcode.js",

View file

@ -20,7 +20,8 @@ include('components/lnbits-manage-extension-list.vue') %} {%
include('components/lnbits-language-dropdown.vue') %} {%
include('components/lnbits-payment-list.vue') %} {%
include('components/lnbits-wallet-api-docs.vue') %} {%
include('components/lnbits-wallet-list.vue') %}
include('components/lnbits-wallet-list.vue') %} {%
include('components/lnbits-wallet-share.vue') %}
<template id="lnbits-manage">
<q-list v-if="g.user" dense class="lnbits-drawer__q-list">

View file

@ -0,0 +1,255 @@
<template id="lnbits-wallet-share">
<q-expansion-item
v-if="g.wallet.walletType == 'lightning'"
group="extras"
icon="share"
:label="$t('share_wallet')"
>
<template v-slot:header>
<q-item-section avatar>
<q-avatar icon="share" style="margin-left: -5px" />
</q-item-section>
<q-item-section>
<span v-text="$t('share_wallet')"></span>
</q-item-section>
<q-item-section side v-if="walletPendingRequests.length">
<div class="row items-center">
<q-icon name="hail" color="secondary" size="24px" />
<span v-text="walletPendingRequests.length"></span>
</div>
</q-item-section>
</template>
<q-card>
<q-card-section>
You can invite other users to have access to this wallet.
<br />
The access is limitted by the permission you grant.
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-5">
<q-input
v-model="walletShareInvite.username"
@keyup.enter="inviteUserToWallet()"
label="Username"
hint="Invite user to this wallet"
dense
>
</q-input>
</div>
<div class="col-6">
<q-select
:options="permissionOptions"
v-model="walletShareInvite.permissions"
emit-value
map-options
multiple
use-chips
dense
class="q-pl-md"
hint="Select permissions for this user"
></q-select>
</div>
<div class="col-1">
<q-btn
@click="inviteUserToWallet()"
dense
flat
icon="person_add_alt"
class="float-right"
></q-btn>
</div>
</div>
</q-card-section>
<q-separator class="q-mt-lg"></q-separator>
<q-expansion-item
group="wallet_shares"
dense
expand-separator
icon="share"
:label="'Shared With (' + walletApprovedShares.length + ')'"
>
<q-card>
<q-card-section v-if="walletApprovedShares.length">
<div v-for="share in walletApprovedShares" class="row q-mb-xs">
<div class="col-3 q-mt-md">
<strong v-text="share.username"></strong>
</div>
<div class="col-1 q-mt-sm">
<q-icon v-if="share.comment" name="add_comment">
<q-tooltip v-text="share.comment"></q-tooltip>
</q-icon>
</div>
<div class="col-6">
<q-select
v-model="share.permissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
></q-select>
</div>
<div class="col-1 q-mt-sm">
<q-btn
flat
color="red"
icon="delete"
outline
class="full-width"
@click="deleteSharePermission(share)"
></q-btn>
</div>
<div class="col-1 q-mt-sm">
<q-btn
dense
flat
color="primary"
icon="check"
class="full-width"
@click="updateSharePermissions(share)"
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section v-else>
<span>This wallet is not shared with anyone.</span>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
group="wallet_shares"
dense
expand-separator
icon="group_add"
:label="'Pending Invitations (' + walletPendingInvites.length + ')'"
>
<q-card>
<q-card-section v-if="walletPendingInvites.length">
<div v-for="share in walletPendingInvites" class="row q-mb-xs">
<div class="col-3 q-mt-md">
<strong v-text="share.username"></strong>
</div>
<div class="col-8">
<q-select
v-model="share.permissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
></q-select>
</div>
<div class="col-1 q-mt-sm">
<q-btn
flat
color="red"
icon="delete"
outline
class="full-width"
@click="deleteSharePermission(share)"
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section v-else>
<span>No pending invites.</span>
</q-card-section>
</q-card>
</q-expansion-item>
<q-card-section> </q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
v-else-if="g.wallet.walletType == 'lightning-shared'"
group="extras"
icon="supervisor_account"
:label="$t('shared_wallet')"
>
<q-card>
<q-card-section>
This wallet does not belong to you. It is a shared Lightning wallet.
<br />
The owner can revoke the permissions at any moment.
</q-card-section>
<q-card-section>
<q-item dense class="q-pa-none">
<q-item-section>
<q-item-label>
<strong>Shared Wallet ID: </strong
><em
v-text="
walletIdHidden ? '****************' : g.wallet.sharedWalletId
"
></em>
</q-item-label>
</q-item-section>
<q-item-section side>
<div>
<q-icon
:name="walletIdHidden ? 'visibility_off' : 'visibility'"
class="cursor-pointer"
@click="walletIdHidden = !walletIdHidden"
></q-icon>
<q-icon
name="content_copy"
class="cursor-pointer q-ml-sm"
@click="copyText(g.wallet.sharedWalletId)"
></q-icon>
<q-icon name="qr_code" class="cursor-pointer q-ml-sm">
<q-popup-proxy>
<div class="q-pa-md">
<lnbits-qrcode
:value="g.wallet.sharedWalletId"
:show-buttons="false"
></lnbits-qrcode>
</div>
</q-popup-proxy>
</q-icon>
</div>
</q-item-section>
</q-item>
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-3 q-mt-md">
<strong>Permissions:</strong>
</div>
<div class="col-9">
<q-select
v-model="g.wallet.sharePermissions"
:options="permissionOptions"
emit-value
map-options
multiple
use-chips
dense
disable
></q-select>
</div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
v-else
group="extras"
icon="question_mark"
:label="$t('share_wallet')"
>
<q-card>
<q-card-section>
Unknown wallet type:
<strong v-text="g.wallet.walletType" class="q-ml-md"></strong>
</q-card-section>
</q-card>
</q-expansion-item>
</template>

View file

@ -121,6 +121,7 @@
"js/components/admin/lnbits-admin-audit.js",
"js/components/lnbits-wallet-list.js",
"js/components/lnbits-wallet-api-docs.js",
"js/components/lnbits-wallet-share.js",
"js/components/lnbits-home-logos.js",
"js/components/lnbits-new-user-wallet.js",
"js/components/lnbits-qrcode.js",