v1 feat: Vue Routes (#2872)

This commit is contained in:
Arc
2025-01-16 13:23:34 +02:00
committed by GitHub
parent 5abfbdd07a
commit 6a08d20fe8
28 changed files with 1919 additions and 1597 deletions
+122 -32
View File
@@ -115,7 +115,7 @@
</div>
</template>
<q-list>
<q-item tag="a" href="/account" clickable v-close-popup
<q-item to="/account" clickable v-close-popup
><q-item-section>
<q-icon name="person" />
</q-item-section>
@@ -128,7 +128,7 @@
<q-item-label> </q-item-label>
</q-item-section>
</q-item>
<q-item tag="a" href="/account#theme" clickable v-close-popup
<q-item to="/account#theme" clickable v-close-popup
><q-item-section>
<q-icon
:name="$q.dark.isActive ? 'dark_mode' : 'light_mode'"
@@ -170,8 +170,22 @@
show-if-above
:elevated="$q.screen.lt.md"
>
<lnbits-wallet-list :balance="balance"></lnbits-wallet-list>
<q-item-label
:style="$q.dark.isActive ? 'color:rgba(255, 255, 255, 0.64)' : ''"
class="q-item__label q-item__label--header"
header
v-text="$t('wallets')"
></q-item-label>
<q-btn
flat
:icon=" walletFlip ? 'keyboard_arrow_right' : 'keyboard_arrow_down'"
class="absolute-top-right"
@click="flipWallets($q.screen.lt.md)"
></q-btn>
<lnbits-wallet-list
v-if="!walletFlip"
:balance="balance"
></lnbits-wallet-list>
<lnbits-manage
:show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'"
:show-users="'{{LNBITS_ADMIN_UI}}' == 'True'"
@@ -184,7 +198,73 @@
{% endblock %} {% block page_container %}
<q-page-container>
<q-page class="q-px-md q-py-lg" :class="{'q-px-lg': $q.screen.gt.xs}">
{% block page %}{% endblock %}
<q-scroll-area
v-if="walletFlip"
style="
height: 130px;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
"
>
<div class="row no-wrap q-gutter-md q-pr-md">
<q-card
v-for="wallet in g.user.wallets"
:key="wallet.id"
clickable
@click="selectWallet(wallet)"
class="wallet-list-card"
style="text-decoration: none"
:style="
g.wallet && g.wallet.id === wallet.id
? `border: 1px solid ${primaryColor}; width: 250px; text-decoration: none; cursor: pointer;`
: 'width: 250px; text-decoration: none; border: 0px; cursor: pointer;'
"
:class="{
'active-wallet-card': g.wallet && g.wallet.id === wallet.id
}"
>
<q-card-section>
<div class="row items-center">
<q-avatar
size="lg"
:color="
g.wallet && g.wallet.id === wallet.id
? $q.dark.isActive
? 'primary'
: 'primary'
: 'grey-5'
"
>
<q-icon
name="flash_on"
:size="$q.dark.isActive ? '21px' : '20px'"
:color="$q.dark.isActive ? 'black' : 'grey-3'"
></q-icon>
</q-avatar>
<div
class="text-h6 q-pl-md"
:class="{
'text-bold': g.wallet && g.wallet.id === wallet.id
}"
v-text="wallet.name"
></div>
</div>
<div class="row items-center q-pt-sm">
<h6 class="q-my-none text-no-wrap">
<strong v-text="wallet.fsat"></strong>
<small> {{LNBITS_DENOMINATION}}</small>
</h6>
</div>
</q-card-section>
</q-card>
</div>
</q-scroll-area>
<router-view v-if="isVueRoute"></router-view>
<!-- FastAPI Content -->
<div v-else>{% block page %}{% endblock %}</div>
</q-page>
</q-page-container>
{% endblock %} {% block footer %}
@@ -241,33 +321,43 @@
<script src="{{ static_url_for('static', url) }}"></script>
{% endfor %}
<script type="text/javascript">
const SITE_DESCRIPTION = {{ SITE_DESCRIPTION | tojson}}
const themes = {{ LNBITS_THEME_OPTIONS | tojson }}
const LNBITS_DENOMINATION = {{ LNBITS_DENOMINATION | tojson }}
const LNBITS_VERSION = {{ LNBITS_VERSION | tojson }}
const LNBITS_QR_LOGO = {{ LNBITS_QR_LOGO | tojson }}
if (themes && themes.length) {
window.allowedThemes = themes.map(str => str.trim())
}
window.langs = [
{ value: 'en', label: 'English', display: '🇬🇧 EN' },
{ value: 'de', label: 'Deutsch', display: '🇩🇪 DE' },
{ value: 'es', label: 'Español', display: '🇪🇸 ES' },
{ value: 'jp', label: '日本語', display: '🇯🇵 JP' },
{ value: 'cn', label: '中文', display: '🇨🇳 CN' },
{ value: 'fr', label: 'Français', display: '🇫🇷 FR' },
{ value: 'it', label: 'Italiano', display: '🇮🇹 IT' },
{ value: 'pi', label: 'Pirate', display: '🏴‍☠️ PI' },
{ value: 'nl', label: 'Nederlands', display: '🇳🇱 NL' },
{ value: 'we', label: 'Cymraeg', display: '🏴󠁧󠁢󠁷󠁬󠁳󠁿 CY' },
{ value: 'pl', label: 'Polski', display: '🇵🇱 PL' },
{ value: 'pt', label: 'Português', display: '🇵🇹 PT' },
{ value: 'br', label: 'Português do Brasil', display: '🇧🇷 BR' },
{ value: 'cs', label: 'Česky', display: '🇨🇿 CS' },
{ value: 'sk', label: 'Slovensky', display: '🇸🇰 SK' },
{ value: 'kr', label: '한국어', display: '🇰🇷 KR' },
{ value: 'fi', label: 'Suomi', display: '🇫🇮 FI' }
]
const SITE_DESCRIPTION = {{ SITE_DESCRIPTION | tojson}}
const themes = {{ LNBITS_THEME_OPTIONS | tojson }}
const LNBITS_DENOMINATION = {{ LNBITS_DENOMINATION | tojson }}
const LNBITS_VERSION = {{ LNBITS_VERSION | tojson }}
const LNBITS_QR_LOGO = {{ LNBITS_QR_LOGO | tojson }}
if (themes && themes.length) {
window.allowedThemes = themes.map(str => str.trim())
}
window.langs = [
{ value: 'en', label: 'English', display: '🇬🇧 EN' },
{ value: 'de', label: 'Deutsch', display: '🇩🇪 DE' },
{ value: 'es', label: 'Español', display: '🇪🇸 ES' },
{ value: 'jp', label: '日本語', display: '🇯🇵 JP' },
{ value: 'cn', label: '中文', display: '🇨🇳 CN' },
{ value: 'fr', label: 'Français', display: '🇫🇷 FR' },
{ value: 'it', label: 'Italiano', display: '🇮🇹 IT' },
{ value: 'pi', label: 'Pirate', display: '🏴‍☠️ PI' },
{ value: 'nl', label: 'Nederlands', display: '🇳🇱 NL' },
{ value: 'we', label: 'Cymraeg', display: '🏴󠁧󠁢󠁷󠁬󠁳󠁿 CY' },
{ value: 'pl', label: 'Polski', display: '🇵🇱 PL' },
{ value: 'pt', label: 'Português', display: '🇵🇹 PT' },
{ value: 'br', label: 'Português do Brasil', display: '🇧🇷 BR' },
{ value: 'cs', label: 'Česky', display: '🇨🇿 CS' },
{ value: 'sk', label: 'Slovensky', display: '🇸🇰 SK' },
{ value: 'kr', label: '한국어', display: '🇰🇷 KR' },
{ value: 'fi', label: 'Suomi', display: '🇫🇮 FI' }
]
window.LOCALE = 'en'
window.dateFormat = 'YYYY-MM-DD HH:mm'
window.i18n = new VueI18n.createI18n({
locale: window.LOCALE,
fallbackLocale: window.LOCALE,
messages: window.localisation
})
const websocketPrefix =
window.location.protocol === 'http:' ? 'ws://' : 'wss://'
const websocketUrl = `${'http:' ? 'ws://' : 'wss://'}${window.location.host}/api/v1/ws`
</script>
{% block scripts %}{% endblock %} {% for url in INCLUDED_COMPONENTS %}
<script src="{{ static_url_for('static', url) }}"></script>
+23 -58
View File
@@ -1,23 +1,21 @@
<template id="lnbits-wallet-list">
<q-list
v-if="user && user.wallets.length"
v-if="g.user && g.user.wallets.length"
dense
class="lnbits-drawer__q-list"
>
<q-item-label header v-text="$t('wallets')"></q-item-label>
<q-item
v-for="wallet in wallets"
:key="wallet.id"
v-for="walletRec in g.user.wallets"
:key="walletRec.id"
clickable
:active="activeWallet && activeWallet.id === wallet.id"
tag="a"
:href="wallet.url"
:active="g.wallet && g.wallet.id === walletRec.id"
@click="selectWallet(walletRec)"
>
<q-item-section side>
<q-avatar
size="md"
:color="
activeWallet && activeWallet.id === wallet.id
g.wallet && g.wallet.id === walletRec.id
? $q.dark.isActive
? 'primary'
: 'primary'
@@ -33,27 +31,23 @@
</q-item-section>
<q-item-section>
<q-item-label lines="1"
><span v-text="wallet.name"></span
><span v-text="walletRec.name"></span
></q-item-label>
<q-item-label v-if="LNBITS_DENOMINATION != 'sats'" caption>
<span
v-text="
parseFloat(String(wallet.live_fsat).replaceAll(',', '')) / 100
parseFloat(String(walletRec.fsat).replaceAll(',', '')) / 100
"
></span
>&nbsp;
<span v-text="LNBITS_DENOMINATION"></span>
</q-item-label>
<q-item-label v-else caption>
<span v-text="wallet.live_fsat"></span>&nbsp;
<span v-text="walletRec.fsat"></span>&nbsp;
<span v-text="LNBITS_DENOMINATION"></span>
</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>
<q-item-section side v-show="g.wallet && g.wallet.id === walletRec.id">
</q-item-section>
</q-item>
<q-item clickable @click="showForm = !showForm">
@@ -96,7 +90,9 @@
<template id="lnbits-extension-list">
<q-list
v-if="user && (userExtensions.length > 0 || !!searchTerm)"
v-if="
(g.user && userExtensions && userExtensions.length > 0) || !!searchTerm
"
dense
class="lnbits-drawer__q-list"
>
@@ -138,16 +134,10 @@
</template>
<template id="lnbits-manage">
<q-list v-if="user" dense class="lnbits-drawer__q-list">
<q-list v-if="g.user" dense class="lnbits-drawer__q-list">
<q-item-label header v-text="$t('manage')"></q-item-label>
<div v-if="user.admin">
<q-item
v-if="showAdmin"
clickable
tag="a"
href="/admin"
:active="isActive('/admin')"
>
<div v-if="g.user.admin">
<q-item v-if="showAdmin" to="/admin">
<q-item-section side>
<q-icon
name="admin_panel_settings"
@@ -159,13 +149,7 @@
<q-item-label lines="1" v-text="$t('server')"></q-item-label>
</q-item-section>
</q-item>
<q-item
v-if="showNode"
clickable
tag="a"
href="/node"
:active="isActive('/node')"
>
<q-item v-if="showNode" to="/node">
<q-item-section side>
<q-icon
name="developer_board"
@@ -177,13 +161,7 @@
<q-item-label lines="1" v-text="$t('node')"></q-item-label>
</q-item-section>
</q-item>
<q-item
v-if="showUsers"
clickable
tag="a"
href="/users"
:active="isActive('/users')"
>
<q-item v-if="showUsers" to="/users">
<q-item-section side>
<q-icon
name="groups"
@@ -195,13 +173,7 @@
<q-item-label lines="1" v-text="$t('users')"></q-item-label>
</q-item-section>
</q-item>
<q-item
v-if="showAudit"
clickable
tag="a"
href="/audit"
:active="isActive('/audit')"
>
<q-item v-if="showAudit" to="/audit">
<q-item-section side>
<q-icon
name="playlist_add_check_circle"
@@ -214,13 +186,7 @@
</q-item-section>
</q-item>
</div>
<q-item
v-if="showExtensions"
clickable
tag="a"
href="/extensions"
:active="isActive('/extensions')"
>
<q-item v-if="showExtensions" to="/extensions">
<q-item-section side>
<q-icon
name="extension"
@@ -236,7 +202,7 @@
</template>
<template id="lnbits-payment-details">
<div class="q-py-md" style="text-align: left">
<div v-if="payment" class="q-py-md" style="text-align: left">
<div v-if="payment.tag" class="row justify-center q-mb-md">
<q-badge v-if="hasTag" color="yellow" text-color="black">
#<span v-text="payment.tag"></span>
@@ -514,7 +480,7 @@
v-model="scope.value"
dense
autofocus
@keyup.enter="scope.set"
@keyup.enter="updateBalance(scope)"
>
<template v-slot:append>
<q-icon name="edit" />
@@ -568,9 +534,8 @@
<template id="payment-list">
<div class="row items-center no-wrap">
<div class="col">
<div class="col" v-if="!mobileSimple || $q.screen.gt.sm">
<q-input
v-if="!mobileSimple"
:label="$t('search_by_tag_memo_amount')"
dense
class="q-pr-xl"
+18 -3
View File
@@ -1,6 +1,9 @@
{% macro window_vars(user, wallet) -%}
<script>
window.extensions = {{ EXTENSIONS | tojson | safe }};
{% macro window_vars(user, wallet, extensions, extension_data) -%}
<script id="window-vars-script">
window.extensions = JSON.parse('{{ EXTENSIONS | tojson | safe }}');
{% if extension_data %}
window.extension_data = {{ extension_data | tojson | safe }};
{% endif %}
{% if currencies %}
window.currencies = {{ currencies | tojson | safe }};
{% endif %}
@@ -11,4 +14,16 @@
window.wallet = JSON.parse({{ wallet | tojson | safe }});
{% endif %}
</script>
<script>
//Needed for Vue to create the app on first load (although called on every page, its only loaded once)
window.app = Vue.createApp({
el: '#vue',
mixins: [window.windowMixin],
data() {
return {
updatePayments: false
}
}
})
</script>
{%- endmacro %}