refactor into <lnbits-header /> component (#3488)

This commit is contained in:
dni ⚡ 2025-11-10 13:56:32 +01:00 committed by GitHub
parent 6474aeb982
commit c9270bbf7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 217 additions and 147 deletions

File diff suppressed because one or more lines are too long

View file

@ -102,7 +102,23 @@ window.app.component('lnbits-extension-list', {
window.app.component('lnbits-manage', { window.app.component('lnbits-manage', {
mixins: [window.windowMixin], mixins: [window.windowMixin],
template: '#lnbits-manage', template: '#lnbits-manage',
props: ['showAdmin', 'showNode', 'showExtensions', 'showUsers', 'showAudit'], computed: {
showAdmin() {
return this.LNBITS_ADMIN_UI
},
showUsers() {
return this.LNBITS_ADMIN_UI
},
showNode() {
return this.LNBITS_NODE_UI
},
showAudit() {
return this.LNBITS_AUDIT_ENABLED
},
showExtensions() {
return this.LNBITS_EXTENSIONS_DEACTIVATE_ALL === false
}
},
methods: { methods: {
isActive(path) { isActive(path) {
return window.location.pathname === path return window.location.pathname === path

View file

@ -0,0 +1,57 @@
window.app.component('lnbits-header', {
template: '#lnbits-header',
mixins: [window.windowMixin],
computed: {
denomination() {
return this.LNBITS_DENOMINATION || 'sat'
},
hasServiceFeeMax() {
return (
this.g.user &&
this.LNBITS_SERVICE_FEE_MAX &&
this.LNBITS_SERVICE_FEE_MAX > 0
)
},
serviceFeeMax() {
return this.LNBITS_SERVICE_FEE_MAX || 0
},
hasServiceFee() {
return (
this.g.user && this.LNBITS_SERVICE_FEE && this.LNBITS_SERVICE_FEE > 0
)
},
serviceFee() {
return this.LNBITS_SERVICE_FEE || 0
},
hasCustomBadge() {
return this.LNBITS_CUSTOM_BADGE && this.LNBITS_CUSTOM_BADGE != ''
},
customBadge() {
return this.LNBITS_CUSTOM_BADGE || ''
},
customBadgeColor() {
return this.LNBITS_CUSTOM_BADGE_COLOR || ''
},
title() {
return this.SITE_TITLE
},
titleIsLnbits() {
return this.SITE_TITLE == 'LNbits'
},
customLogoUrl() {
return this.USE_CUSTOM_LOGO || null
},
userPictureUrl() {
return this.g.user.config.picture
},
hasUserPicture() {
return this.g.user && this.g.user.config && this.g.user.config.picture
},
showAdmin() {
return this.g.user && (this.g.user.super_user || this.g.user.admin)
},
showVoidwallet() {
return this.g.user && this.VOIDWALLET == true
}
}
})

View file

@ -70,6 +70,7 @@
"js/components/lnbits-qrcode.js", "js/components/lnbits-qrcode.js",
"js/components/lnbits-qrcode-lnurl.js", "js/components/lnbits-qrcode-lnurl.js",
"js/components/lnbits-footer.js", "js/components/lnbits-footer.js",
"js/components/lnbits-header.js",
"js/components/extension-settings.js", "js/components/extension-settings.js",
"js/components/data-fields.js", "js/components/data-fields.js",
"js/components/payment-list.js", "js/components/payment-list.js",

View file

@ -33,143 +33,7 @@
<body data-theme="bitcoin"> <body data-theme="bitcoin">
<div id="vue"> <div id="vue">
<q-layout view="hHh lpR lfr" v-cloak> <q-layout view="hHh lpR lfr" v-cloak>
<q-header bordered class="bg-marginal-bg"> <lnbits-header></lnbits-header>
<!-- VoidWallet Warning Banner -->
{% if VOIDWALLET %}
<q-banner v-if="g.user" class="bg-warning text-white" dense>
<template v-slot:avatar>
<q-icon name="warning" color="white" />
</template>
<a
v-if="g.user && (g.user.super_user || g.user.admin)"
href="/admin"
style="color: white; text-decoration: underline; cursor: pointer"
v-text="$t('voidwallet_active_admin')"
></a>
<span v-else v-text="$t('voidwallet_active_user')"></span>
</q-banner>
{% endif %}
<q-toolbar>
{% block drawer_toggle %}
<q-btn
dense
flat
round
icon="menu"
@click="g.visibleDrawer = !g.visibleDrawer"
></q-btn>
{% endblock %}
<q-toolbar-title>
{% block toolbar_title %}
<q-btn flat no-caps dense size="lg" type="a" href="/"
>{% if USE_CUSTOM_LOGO %}
<img height="30px" alt="Logo" src="{{ USE_CUSTOM_LOGO }}" />
{%else%} {% if SITE_TITLE != 'LNbits' %} {{ SITE_TITLE }} {%
else %}
<span><strong>LN</strong>bits</span> {% endif %} {%endif%} </q-btn
>{% endblock %} {% block toolbar_subtitle %}
<q-badge v-if="g.user && g.user.super_user">Super User</q-badge>
<q-badge v-else-if="g.user && g.user.admin">Admin User</q-badge>
{% endblock %}
</q-toolbar-title>
{% block beta %} {% if LNBITS_CUSTOM_BADGE is not none and
LNBITS_CUSTOM_BADGE != "" %}
<q-badge
v-show="$q.screen.gt.sm"
color="{{ LNBITS_CUSTOM_BADGE_COLOR }}"
class="q-mr-md"
label="{{LNBITS_CUSTOM_BADGE|e}}"
>
</q-badge>
{% endif %} {% if LNBITS_SERVICE_FEE > 0 %}
<q-badge
v-show="$q.screen.gt.sm"
v-if="g.user"
color="green"
class="q-mr-md"
>
{% if LNBITS_SERVICE_FEE_MAX > 0 %}
<span
v-text='$t("service_fee_max_badge", { amount: "{{ LNBITS_SERVICE_FEE }}", max: "{{ LNBITS_SERVICE_FEE_MAX }}", denom: "{{ LNBITS_DENOMINATION }}"})'
></span>
{%else%}
<span
v-text='$t("service_fee_badge", { amount: "{{ LNBITS_SERVICE_FEE}}"})'
></span>
{%endif%}
<q-tooltip
><span v-text='$t("service_fee_tooltip")'></span
></q-tooltip>
</q-badge>
{%endif%} {% endblock %}
<q-badge v-if="g.offline" color="red" class="q-mr-md">
<span>OFFLINE</span>
</q-badge>
<q-btn-dropdown
v-if="g.user || isUserAuthorized"
flat
rounded
size="sm"
class="q-pl-sm"
>
<template v-slot:label>
<div>
{%if user and user.config and user.config.picture%}
<img src="{{user.config.picture}}" style="max-width: 32px" />
{%else%}
<q-icon name="account_circle" />
{%endif%}
</div>
</template>
<q-list>
<q-item to="/account" clickable v-close-popup
><q-item-section>
<q-icon name="person" />
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('my_account')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
<q-item to="/account#theme" clickable v-close-popup
><q-item-section>
<q-icon
:name="$q.dark.isActive ? 'dark_mode' : 'light_mode'"
/>
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('theme')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
<q-separator></q-separator>
<q-item clickable v-close-popup @click="logout"
><q-item-section>
<q-icon name="logout" />
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('logout')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-toolbar>
</q-header>
{% block drawer %} {% block drawer %}
<q-drawer <q-drawer
@ -205,18 +69,13 @@
</q-btn> </q-btn>
</q-item-section> </q-item-section>
</q-item> </q-item>
<lnbits-wallet-list <lnbits-wallet-list
v-if="!walletFlip" v-if="!walletFlip"
:balance="balance" :balance="balance"
@wallet-action="handleWalletAction" @wallet-action="handleWalletAction"
></lnbits-wallet-list> ></lnbits-wallet-list>
<lnbits-manage <lnbits-manage />
:show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'"
:show-users="'{{LNBITS_ADMIN_UI}}' == 'True'"
:show-audit="'{{LNBITS_AUDIT_ENABLED}}' == 'True'"
:show-node="'{{LNBITS_NODE_UI}}' == 'True'"
:show-extensions="'{{LNBITS_EXTENSIONS_DEACTIVATE_ALL}}' == 'False'"
></lnbits-manage>
<lnbits-extension-list class="q-pb-xl"></lnbits-extension-list> <lnbits-extension-list class="q-pb-xl"></lnbits-extension-list>
</q-scroll-area> </q-scroll-area>
</q-drawer> </q-drawer>

View file

@ -11,7 +11,8 @@ include('components/admin/library.vue') %} {%
include('components/admin/notifications.vue') %} {% include('components/admin/notifications.vue') %} {%
include('components/admin/server.vue') %} {% include('components/admin/server.vue') %} {%
include('components/new_user_wallet.vue') %} {% include('components/new_user_wallet.vue') %} {%
include('components/lnbits-footer.vue') %} include('components/lnbits-footer.vue') %} {%
include('components/lnbits-header.vue') %}
<template id="lnbits-wallet-list"> <template id="lnbits-wallet-list">
<q-list <q-list

View file

@ -0,0 +1,135 @@
<template id="lnbits-header">
<q-header bordered class="bg-marginal-bg">
<q-banner v-if="showVoidwallet" class="bg-warning text-white" dense>
<template v-slot:avatar>
<q-icon name="warning" color="white" />
</template>
<a
v-if="showAdmin"
href="/admin"
style="color: white; text-decoration: underline; cursor: pointer"
v-text="$t('voidwallet_active_admin')"
></a>
<span v-else v-text="$t('voidwallet_active_user')"></span>
</q-banner>
<q-toolbar>
<q-btn
dense
flat
round
icon="menu"
@click="g.visibleDrawer = !g.visibleDrawer"
></q-btn>
<q-toolbar-title>
<q-btn flat no-caps dense size="lg" type="a" href="/">
<img
v-if="customLogoUrl"
height="30px"
alt="Logo"
:src="customLogoUrl"
/>
<span v-else-if="!titleIsLnbits"><strong>LN</strong>bits</span>
<span v-else v-text="title"></span>
</q-btn>
<q-badge v-if="g.user && g.user.super_user">Super User</q-badge>
<q-badge v-else-if="g.user && g.user.admin">Admin User</q-badge>
</q-toolbar-title>
<q-badge
class="q-mr-md"
v-show="$q.screen.gt.sm"
v-if="hasCustomBadge"
:label="customBadge"
:color="customBadgeColor"
>
</q-badge>
<q-badge
v-show="$q.screen.gt.sm"
v-if="hasServiceFee"
color="green"
class="q-mr-md"
>
<span
v-if="hasServiceFeeMax"
v-text="
$t('service_fee_max_badge', {
amount: serviceFee,
max: serviceFeeMax,
denom: denomination
})
"
></span>
<span
v-else
v-text="$t('service_fee_badge', {amount: serviceFee})"
></span>
<q-tooltip><span v-text="$t('service_fee_tooltip')"></span></q-tooltip>
</q-badge>
<q-badge v-if="g.offline" color="red" class="q-mr-md">
<span>OFFLINE</span>
</q-badge>
<q-btn-dropdown
v-if="g.user || isUserAuthorized"
flat
rounded
size="sm"
class="q-pl-sm"
>
<template v-slot:label>
<div>
<img
v-if="hasUserPicture"
:src="userPictureUrl"
style="max-width: 32px"
/>
<q-icon v-else name="account_circle" />
</div>
</template>
<q-list>
<q-item to="/account" clickable v-close-popup
><q-item-section>
<q-icon name="person" />
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('my_account')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
<q-item to="/account#theme" clickable v-close-popup
><q-item-section>
<q-icon :name="$q.dark.isActive ? 'dark_mode' : 'light_mode'" />
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('theme')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
<q-separator></q-separator>
<q-item clickable v-close-popup @click="logout"
><q-item-section>
<q-icon name="logout" />
</q-item-section>
<q-item-section>
<q-item-label>
<span v-text="$t('logout')"></span>
</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-toolbar>
</q-header>
</template>

View file

@ -122,6 +122,7 @@
"js/components/lnbits-qrcode.js", "js/components/lnbits-qrcode.js",
"js/components/lnbits-qrcode-lnurl.js", "js/components/lnbits-qrcode-lnurl.js",
"js/components/lnbits-footer.js", "js/components/lnbits-footer.js",
"js/components/lnbits-header.js",
"js/components/extension-settings.js", "js/components/extension-settings.js",
"js/components/data-fields.js", "js/components/data-fields.js",
"js/components/payment-list.js", "js/components/payment-list.js",