[feat] Payment labels (#3537)
This commit is contained in:
@@ -21,6 +21,7 @@ include('components/lnbits-manage-wallet-list.vue') %} {%
|
||||
include('components/lnbits-language-dropdown.vue') %} {%
|
||||
include('components/lnbits-payment-list.vue') %} {%
|
||||
include('components/lnbits-wallet-new.vue') %} {%
|
||||
include('components/lnbits-label-selector.vue') %} {%
|
||||
include('components/lnbits-wallet-api-docs.vue') %} {%
|
||||
include('components/lnbits-wallet-share.vue') %} {%
|
||||
include('components/lnbits-wallet-charts.vue') %}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<template id="lnbits-label-selector">
|
||||
<div v-if="g.user.extra.labels?.length">
|
||||
<q-item header>
|
||||
<q-input
|
||||
v-model="labelFilter"
|
||||
:label="$t('filter_labels')"
|
||||
class="full-width"
|
||||
filled
|
||||
dense
|
||||
autofocus
|
||||
>
|
||||
</q-input>
|
||||
</q-item>
|
||||
<q-separator></q-separator>
|
||||
<q-scroll-area style="height: 230px; max-width: 300px">
|
||||
<div v-for="label in g.user.extra.labels" :key="label.name">
|
||||
<q-item
|
||||
v-if="
|
||||
!labelFilter ||
|
||||
label.name.toLowerCase().includes(labelFilter.toLowerCase())
|
||||
"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<q-item-section avatar top>
|
||||
<q-checkbox
|
||||
:model-value="localLabels.includes(label.name)"
|
||||
@click="toggleLabel(label)"
|
||||
dense
|
||||
>
|
||||
</q-checkbox>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section>
|
||||
<q-item-label lines="1"
|
||||
><span v-text="label.name"></span
|
||||
></q-item-label>
|
||||
<q-item-label caption
|
||||
><span v-text="label.description"></span
|
||||
></q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side>
|
||||
<q-badge
|
||||
class="q-pa-sm"
|
||||
size="xs"
|
||||
rounded
|
||||
:style="{
|
||||
backgroundColor: label.color,
|
||||
color: 'white'
|
||||
}"
|
||||
>
|
||||
<span v-text="label.color"></span>
|
||||
</q-badge>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
<q-item footer>
|
||||
<q-btn
|
||||
v-close-popup
|
||||
flat
|
||||
color="grey"
|
||||
class="q-ml-none"
|
||||
icon="highlight_off"
|
||||
@click="clearLabels"
|
||||
>
|
||||
<q-tooltip>
|
||||
<span v-text="$t('clear')"></span>
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-close-popup
|
||||
flat
|
||||
href="/account#labels"
|
||||
color="grey"
|
||||
icon="settings"
|
||||
class="q-ml-auto float-right"
|
||||
>
|
||||
<q-tooltip>
|
||||
<span v-text="$t('manage_labels')"></span>
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-close-popup
|
||||
flat
|
||||
color="primary"
|
||||
class="q-ml-none"
|
||||
:label="$t('ok')"
|
||||
@click="saveLabels"
|
||||
>
|
||||
<q-tooltip>
|
||||
<span v-text="$t('manage_labels')"></span>
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-item>
|
||||
</div>
|
||||
<div v-else class="q-pa-md">
|
||||
<p v-text="$t('no_labels_defined')"></p>
|
||||
<q-btn
|
||||
flat
|
||||
href="/account#labels"
|
||||
color="primary"
|
||||
:label="$t('manage_labels')"
|
||||
></q-btn>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,7 +22,12 @@
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="gt-sm col-auto">
|
||||
<q-btn icon="event" flat color="grey">
|
||||
<q-btn icon="event" flat color="grey" class="q-pa-sm">
|
||||
<q-badge
|
||||
v-if="searchDate?.to || searchDate?.from"
|
||||
color="primary"
|
||||
floating
|
||||
></q-badge>
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="searchDate" mask="YYYY-MM-DD" range />
|
||||
<div class="row">
|
||||
@@ -48,19 +53,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</q-popup-proxy>
|
||||
<q-badge
|
||||
v-if="searchDate?.to || searchDate?.from"
|
||||
class="q-mt-lg q-mr-md"
|
||||
color="primary"
|
||||
rounded
|
||||
floating
|
||||
style="border-radius: 6px"
|
||||
></q-badge>
|
||||
|
||||
<q-tooltip>
|
||||
<span v-text="$t('filter_date')"></span>
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn color="grey" icon="filter_alt" flat>
|
||||
<q-btn icon="local_offer" class="q-pa-sm" flat color="grey">
|
||||
<q-badge
|
||||
v-if="filterLabels.length"
|
||||
color="primary"
|
||||
size="xs"
|
||||
floating
|
||||
v-text="filterLabels.length"
|
||||
></q-badge>
|
||||
<q-tooltip>
|
||||
<span v-text="$t('label_filter')"></span>
|
||||
</q-tooltip>
|
||||
<q-popup-edit class="text-white q-pa-none">
|
||||
<lnbits-label-selector
|
||||
:labels="filterLabels"
|
||||
@update:labels="searchByLabels"
|
||||
></lnbits-label-selector>
|
||||
</q-popup-edit>
|
||||
</q-btn>
|
||||
<q-btn color="grey" icon="filter_alt" class="q-pa-sm" flat>
|
||||
<q-menu>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
@@ -109,7 +125,7 @@
|
||||
persistent
|
||||
icon="archive"
|
||||
split
|
||||
class="q-mr-sm"
|
||||
class="q-mr-sm q-pa-sm"
|
||||
color="grey"
|
||||
@click="exportCSV(false)"
|
||||
>
|
||||
@@ -263,6 +279,42 @@
|
||||
<span class="text-grey-5" v-text="props.row.dateFrom"></span>
|
||||
<q-tooltip><span v-text="props.row.date"></span></q-tooltip>
|
||||
</i>
|
||||
<q-icon
|
||||
@click="selectedPayment = props.row"
|
||||
name="local_offer"
|
||||
color="grey"
|
||||
class="q-ml-sm cursor-pointer"
|
||||
size="xs"
|
||||
>
|
||||
<q-tooltip>
|
||||
<span v-text="$t('add_remove_labels')"></span>
|
||||
</q-tooltip>
|
||||
<q-popup-edit class="text-white q-pa-none">
|
||||
<lnbits-label-selector
|
||||
:labels="props.row.labels"
|
||||
@update:labels="savePaymentLabels"
|
||||
></lnbits-label-selector>
|
||||
</q-popup-edit>
|
||||
</q-icon>
|
||||
<template v-for="label in g.user.extra.labels" :key="label.name">
|
||||
<q-badge
|
||||
v-if="props.row.labels.includes(label.name)"
|
||||
@click="searchByLabels([label.name])"
|
||||
:style="{
|
||||
backgroundColor: label.color,
|
||||
color: isLightColor(label.color) ? 'black' : 'white'
|
||||
}"
|
||||
class="q-ml-sm cursor-pointer"
|
||||
size="xs"
|
||||
dense
|
||||
rounded
|
||||
>
|
||||
<span v-text="label.name"></span>
|
||||
<q-tooltip>
|
||||
<span v-text="label.description || label.name"></span>
|
||||
</q-tooltip>
|
||||
</q-badge>
|
||||
</template>
|
||||
</q-td>
|
||||
<q-td
|
||||
auto-width
|
||||
|
||||
@@ -6,8 +6,17 @@
|
||||
<div class="row items-center justify-between q-gutter-xs">
|
||||
<div class="col">
|
||||
<q-btn @click="updateAccount" unelevated color="primary">
|
||||
<q-badge
|
||||
v-if="isUserTouched"
|
||||
color="negative"
|
||||
size="xs"
|
||||
floating
|
||||
></q-badge>
|
||||
<span v-text="$t('update_account')"></span>
|
||||
</q-btn>
|
||||
<q-badge v-if="isUserTouched" class="q-ml-sm" color="primary">
|
||||
<span v-text="$t('must_save')"></span>
|
||||
</q-badge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -20,6 +29,7 @@
|
||||
<q-card>
|
||||
<q-splitter>
|
||||
<template v-slot:before>
|
||||
<!-- todo: small screen as in settings -->
|
||||
<q-tabs v-model="tab" vertical active-color="primary">
|
||||
<q-tab
|
||||
name="user"
|
||||
@@ -72,6 +82,16 @@
|
||||
><span v-text="$t('assets')"></span
|
||||
></q-tooltip>
|
||||
</q-tab>
|
||||
<q-tab
|
||||
name="labels"
|
||||
icon="local_offer"
|
||||
:label="$q.screen.gt.sm ? $t('labels') : ''"
|
||||
@update="val => (tab = val.name)"
|
||||
>
|
||||
<q-tooltip v-if="!$q.screen.gt.sm"
|
||||
><span v-text="$t('labels')"></span
|
||||
></q-tooltip>
|
||||
</q-tab>
|
||||
</q-tabs>
|
||||
</template>
|
||||
<template v-slot:after>
|
||||
@@ -1027,6 +1047,92 @@
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="labels">
|
||||
<q-card-section>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-sm-12">
|
||||
<q-btn
|
||||
@click="openAddLabelDialog()"
|
||||
:label="$t('add_label')"
|
||||
color="primary"
|
||||
class="full-width"
|
||||
></q-btn>
|
||||
</div>
|
||||
<div class="col-md-1 col-sm-12"></div>
|
||||
<div class="col-md-9 col-sm-12">
|
||||
<q-input
|
||||
:label="$t('search')"
|
||||
dense
|
||||
class="full-width q-pb-xl"
|
||||
v-model="labelsTable.search"
|
||||
>
|
||||
<template v-slot:before>
|
||||
<q-icon name="search"> </q-icon>
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="labelsTable.search !== ''"
|
||||
name="close"
|
||||
@click="labelsTable.search = ''"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator></q-separator>
|
||||
<q-card-section>
|
||||
<q-table
|
||||
:rows="user.extra.labels"
|
||||
:columns="labelsTable.columns"
|
||||
v-model:pagination="labelsTable.pagination"
|
||||
:loading="labelsTable.loading"
|
||||
row-key="name"
|
||||
:filter="labelsTable.search"
|
||||
>
|
||||
<template v-slot:body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td key="actions" :props="props">
|
||||
<q-btn
|
||||
@click="openEditLabelDialog(props.row)"
|
||||
dense
|
||||
flat
|
||||
icon="edit"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
@click="deleteUserLabel(props.row)"
|
||||
dense
|
||||
flat
|
||||
icon="delete"
|
||||
color="negative"
|
||||
class="q-ml-md"
|
||||
></q-btn>
|
||||
</q-td>
|
||||
<q-td key="name" :props="props">
|
||||
<span v-text="props.row.name"></span>
|
||||
</q-td>
|
||||
<q-td key="description" :props="props">
|
||||
<span v-text="props.row.description"></span>
|
||||
</q-td>
|
||||
<q-td key="color" :props="props">
|
||||
<q-badge
|
||||
class="q-pa-sm"
|
||||
:style="{
|
||||
backgroundColor: props.row.color,
|
||||
color: 'white'
|
||||
}"
|
||||
>
|
||||
<span v-text="props.row.color"></span>
|
||||
</q-badge>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</q-scroll-area>
|
||||
</template>
|
||||
@@ -1052,11 +1158,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
@click="runPasswordGuardedFunction()"
|
||||
:label="$t('ok')"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
v-close-popup
|
||||
flat
|
||||
@@ -1064,6 +1165,11 @@
|
||||
class="q-ml-auto"
|
||||
v-text="$t('cancel')"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
@click="runPasswordGuardedFunction()"
|
||||
:label="$t('ok')"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
@@ -1167,4 +1273,81 @@
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="labelsDialog.show" position="top">
|
||||
<q-card class="q-pa-md q-pt-md lnbits__dialog-card">
|
||||
<strong v-text="$t('label')"></strong>
|
||||
<div class="row q-mt-md q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
v-model="labelsDialog.data.name"
|
||||
dense
|
||||
filled
|
||||
:label="$t('name')"
|
||||
>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
v-model="labelsDialog.data.description"
|
||||
dense
|
||||
filled
|
||||
type="textarea"
|
||||
rows="3"
|
||||
:label="$t('description')"
|
||||
>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
v-model="labelsDialog.data.color"
|
||||
filled
|
||||
dense
|
||||
class="my-input"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="colorize" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-color
|
||||
v-model="labelsDialog.data.color"
|
||||
default-view="palette"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
v-close-popup
|
||||
flat
|
||||
color="grey"
|
||||
class="q-ml-auto"
|
||||
v-text="$t('cancel')"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
v-if="
|
||||
user.extra.labels.some(
|
||||
label => label.name === labelsDialog.data.name
|
||||
)
|
||||
"
|
||||
@click="updateUserLabel()"
|
||||
:disable="!labelsDialog.data.name || !labelsDialog.data.color"
|
||||
:label="$t('update_label')"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
v-else
|
||||
@click="addUserLabel()"
|
||||
:disable="!labelsDialog.data.name || !labelsDialog.data.color"
|
||||
:label="$t('add_label')"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user