fix(v2): m005-m007 idempotency + SQLite CREATE INDEX syntax; template self-closing tags
Three live-test bugs caught while wiring the v2 frontend to a real
LNbits regtest instance.
1. **SQLite parse error on CREATE INDEX with schema-prefixed table.**
`CREATE INDEX foo ON satoshimachine.bar (col)` errors with
"near '.': syntax error" on SQLite. PG accepts the prefix on the
table; SQLite expects the schema prefix on the INDEX NAME only,
not on the table. Cleanest portable fix (libra extension pattern):
drop `satoshimachine.` from the table reference inside CREATE INDEX.
The index lands in the same schema as the table regardless.
2. **m005 non-idempotent after partial failure.** The previous bug
above tripped m005 mid-flight (CREATE TABLE super_config + CREATE
TABLE dca_machines succeeded, then the first CREATE INDEX errored
and aborted). LNbits doesn't mark partial migrations done, so the
next boot re-ran m005 — and CREATE TABLE super_config now errored
with "table already exists". To make recovery clean:
- CREATE TABLE IF NOT EXISTS on every table (13 tables)
- CREATE INDEX IF NOT EXISTS on every index (10 indexes)
- super_config seed INSERT wrapped in check-then-insert so the
PK conflict on 'default' on re-run is avoided
3. **Vue compiler error code 30 — self-closing tags on non-void
elements in templates/satmachineadmin/index.html.** The previous
commit `98f82be` on satmachineclient called this out as a known
LNbits UMD gotcha: Vue 3 UMD's compiler doesn't auto-expand `<q-icon />`
the way SFCs do — the browser HTML parser sees the malformed self-
closing tag and aborts compilation. 118 tags expanded from
`<q-foo … />` to `<q-foo …></q-foo>` via mechanical rewrite.
Verified end-to-end against docker regtest-lnbits-1:
- All three migrations (m005, m006, m007) ran cleanly
- Schema has all 8 v2 tables + 10 indexes
- "satmachineadmin v2 loaded" + invoice listener registered
- /satmachineadmin/ returns 200; JS loads; super-config + machines
endpoints respond
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b96837164e
commit
cb19ba3675
2 changed files with 160 additions and 154 deletions
|
|
@ -10,7 +10,7 @@ async def m001_initial_dca_schema(db):
|
||||||
# DCA Clients table
|
# DCA Clients table
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_clients (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_clients (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
user_id TEXT NOT NULL,
|
user_id TEXT NOT NULL,
|
||||||
wallet_id TEXT NOT NULL,
|
wallet_id TEXT NOT NULL,
|
||||||
|
|
@ -27,7 +27,7 @@ async def m001_initial_dca_schema(db):
|
||||||
# DCA Deposits table
|
# DCA Deposits table
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_deposits (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_deposits (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
client_id TEXT NOT NULL,
|
client_id TEXT NOT NULL,
|
||||||
amount INTEGER NOT NULL,
|
amount INTEGER NOT NULL,
|
||||||
|
|
@ -43,7 +43,7 @@ async def m001_initial_dca_schema(db):
|
||||||
# DCA Payments table
|
# DCA Payments table
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_payments (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_payments (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
client_id TEXT NOT NULL,
|
client_id TEXT NOT NULL,
|
||||||
amount_sats INTEGER NOT NULL,
|
amount_sats INTEGER NOT NULL,
|
||||||
|
|
@ -61,7 +61,7 @@ async def m001_initial_dca_schema(db):
|
||||||
# Lamassu Configuration table
|
# Lamassu Configuration table
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.lamassu_config (
|
CREATE TABLE IF NOT EXISTS satoshimachine.lamassu_config (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
host TEXT NOT NULL,
|
host TEXT NOT NULL,
|
||||||
port INTEGER NOT NULL DEFAULT 5432,
|
port INTEGER NOT NULL DEFAULT 5432,
|
||||||
|
|
@ -90,7 +90,7 @@ async def m001_initial_dca_schema(db):
|
||||||
# Lamassu Transactions table (for audit trail)
|
# Lamassu Transactions table (for audit trail)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.lamassu_transactions (
|
CREATE TABLE IF NOT EXISTS satoshimachine.lamassu_transactions (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
lamassu_transaction_id TEXT NOT NULL UNIQUE,
|
lamassu_transaction_id TEXT NOT NULL UNIQUE,
|
||||||
fiat_amount INTEGER NOT NULL,
|
fiat_amount INTEGER NOT NULL,
|
||||||
|
|
@ -200,7 +200,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# The only thing the LNbits super has direct DB control over in this extension.
|
# The only thing the LNbits super has direct DB control over in this extension.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.super_config (
|
CREATE TABLE IF NOT EXISTS satoshimachine.super_config (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
super_fee_pct DECIMAL(10,4) NOT NULL DEFAULT 0.0000,
|
super_fee_pct DECIMAL(10,4) NOT NULL DEFAULT 0.0000,
|
||||||
super_fee_wallet_id TEXT,
|
super_fee_wallet_id TEXT,
|
||||||
|
|
@ -208,6 +208,12 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
# Idempotent seed: check before insert so re-runs after a partial-
|
||||||
|
# failure recovery don't trip the PK conflict.
|
||||||
|
existing = await db.fetchone(
|
||||||
|
"SELECT id FROM satoshimachine.super_config WHERE id = 'default'"
|
||||||
|
)
|
||||||
|
if not existing:
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"INSERT INTO satoshimachine.super_config (id, super_fee_pct) "
|
"INSERT INTO satoshimachine.super_config (id, super_fee_pct) "
|
||||||
"VALUES ('default', 0.0000)"
|
"VALUES ('default', 0.0000)"
|
||||||
|
|
@ -218,7 +224,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# is missing the (net_sats, fee_sats) split — see plan's lamassu-next ask #1.
|
# is missing the (net_sats, fee_sats) split — see plan's lamassu-next ask #1.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_machines (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_machines (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
operator_user_id TEXT NOT NULL,
|
operator_user_id TEXT NOT NULL,
|
||||||
machine_npub TEXT NOT NULL UNIQUE,
|
machine_npub TEXT NOT NULL UNIQUE,
|
||||||
|
|
@ -234,15 +240,15 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_machines_operator_idx "
|
"CREATE INDEX IF NOT EXISTS dca_machines_operator_idx "
|
||||||
"ON satoshimachine.dca_machines (operator_user_id)"
|
"ON dca_machines (operator_user_id)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# dca_clients — LP registrations scoped per (machine, user). One LP can hold
|
# dca_clients — LP registrations scoped per (machine, user). One LP can hold
|
||||||
# positions across many machines (and many operators) on the same instance.
|
# positions across many machines (and many operators) on the same instance.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_clients (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_clients (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
machine_id TEXT NOT NULL,
|
machine_id TEXT NOT NULL,
|
||||||
user_id TEXT NOT NULL,
|
user_id TEXT NOT NULL,
|
||||||
|
|
@ -259,19 +265,19 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE UNIQUE INDEX dca_clients_machine_user_uq "
|
"CREATE UNIQUE INDEX IF NOT EXISTS dca_clients_machine_user_uq "
|
||||||
"ON satoshimachine.dca_clients (machine_id, user_id)"
|
"ON dca_clients (machine_id, user_id)"
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_clients_user_idx "
|
"CREATE INDEX IF NOT EXISTS dca_clients_user_idx "
|
||||||
"ON satoshimachine.dca_clients (user_id)"
|
"ON dca_clients (user_id)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# dca_deposits — fiat the operator (or super) records against an LP at a machine.
|
# dca_deposits — fiat the operator (or super) records against an LP at a machine.
|
||||||
# creator_user_id preserves audit trail (resolves a v1 tech-debt finding).
|
# creator_user_id preserves audit trail (resolves a v1 tech-debt finding).
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_deposits (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_deposits (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
client_id TEXT NOT NULL,
|
client_id TEXT NOT NULL,
|
||||||
machine_id TEXT NOT NULL,
|
machine_id TEXT NOT NULL,
|
||||||
|
|
@ -286,8 +292,8 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_deposits_client_idx "
|
"CREATE INDEX IF NOT EXISTS dca_deposits_client_idx "
|
||||||
"ON satoshimachine.dca_deposits (client_id, created_at DESC)"
|
"ON dca_deposits (client_id, created_at DESC)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# dca_settlements — idempotency table for bitSpire-driven settlements.
|
# dca_settlements — idempotency table for bitSpire-driven settlements.
|
||||||
|
|
@ -306,7 +312,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# section "Customer discounts".
|
# section "Customer discounts".
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_settlements (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_settlements (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
machine_id TEXT NOT NULL,
|
machine_id TEXT NOT NULL,
|
||||||
payment_hash TEXT NOT NULL UNIQUE,
|
payment_hash TEXT NOT NULL UNIQUE,
|
||||||
|
|
@ -332,8 +338,8 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_settlements_machine_idx "
|
"CREATE INDEX IF NOT EXISTS dca_settlements_machine_idx "
|
||||||
"ON satoshimachine.dca_settlements (machine_id, created_at DESC)"
|
"ON dca_settlements (machine_id, created_at DESC)"
|
||||||
)
|
)
|
||||||
# payment_hash UNIQUE already creates a lookup index — no extra index needed.
|
# payment_hash UNIQUE already creates a lookup index — no extra index needed.
|
||||||
|
|
||||||
|
|
@ -344,7 +350,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# scope must equal 1.0 — enforced at write-time in crud.py.
|
# scope must equal 1.0 — enforced at write-time in crud.py.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_commission_splits (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_commission_splits (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
machine_id TEXT,
|
machine_id TEXT,
|
||||||
operator_user_id TEXT NOT NULL,
|
operator_user_id TEXT NOT NULL,
|
||||||
|
|
@ -357,8 +363,8 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_commission_splits_lookup_idx "
|
"CREATE INDEX IF NOT EXISTS dca_commission_splits_lookup_idx "
|
||||||
"ON satoshimachine.dca_commission_splits (operator_user_id, machine_id)"
|
"ON dca_commission_splits (operator_user_id, machine_id)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# dca_payments — every leg of every distribution. The leg_type discriminator
|
# dca_payments — every leg of every distribution. The leg_type discriminator
|
||||||
|
|
@ -367,7 +373,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# autoforward (see satmachineadmin#8) | refund.
|
# autoforward (see satmachineadmin#8) | refund.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE satoshimachine.dca_payments (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_payments (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
settlement_id TEXT,
|
settlement_id TEXT,
|
||||||
client_id TEXT,
|
client_id TEXT,
|
||||||
|
|
@ -388,16 +394,16 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_payments_client_idx "
|
"CREATE INDEX IF NOT EXISTS dca_payments_client_idx "
|
||||||
"ON satoshimachine.dca_payments (client_id, created_at DESC)"
|
"ON dca_payments (client_id, created_at DESC)"
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_payments_settlement_idx "
|
"CREATE INDEX IF NOT EXISTS dca_payments_settlement_idx "
|
||||||
"ON satoshimachine.dca_payments (settlement_id)"
|
"ON dca_payments (settlement_id)"
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE INDEX dca_payments_operator_idx "
|
"CREATE INDEX IF NOT EXISTS dca_payments_operator_idx "
|
||||||
"ON satoshimachine.dca_payments (operator_user_id, leg_type)"
|
"ON dca_payments (operator_user_id, leg_type)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# dca_telemetry — latest replaceable kind-30078 (public availability beacon)
|
# dca_telemetry — latest replaceable kind-30078 (public availability beacon)
|
||||||
|
|
@ -408,7 +414,7 @@ async def m005_satmachine_v2_overhaul(db):
|
||||||
# lands. Ingest opportunistically; render absent fields gracefully in the UI.
|
# lands. Ingest opportunistically; render absent fields gracefully in the UI.
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
CREATE TABLE satoshimachine.dca_telemetry (
|
CREATE TABLE IF NOT EXISTS satoshimachine.dca_telemetry (
|
||||||
machine_id TEXT PRIMARY KEY,
|
machine_id TEXT PRIMARY KEY,
|
||||||
beacon_cash_in BOOLEAN,
|
beacon_cash_in BOOLEAN,
|
||||||
beacon_cash_out BOOLEAN,
|
beacon_cash_out BOOLEAN,
|
||||||
|
|
@ -473,6 +479,6 @@ async def m007_settlement_claim_and_machine_wallet_unique(db):
|
||||||
"ADD COLUMN processing_claim TEXT"
|
"ADD COLUMN processing_claim TEXT"
|
||||||
)
|
)
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"CREATE UNIQUE INDEX dca_machines_wallet_id_uq "
|
"CREATE UNIQUE INDEX IF NOT EXISTS dca_machines_wallet_id_uq "
|
||||||
"ON satoshimachine.dca_machines (wallet_id)"
|
"ON dca_machines (wallet_id)"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -63,19 +63,19 @@
|
||||||
active-color="primary"
|
active-color="primary"
|
||||||
indicator-color="primary"
|
indicator-color="primary"
|
||||||
narrow-indicator>
|
narrow-indicator>
|
||||||
<q-tab name="fleet" icon="precision_manufacturing" label="Fleet" />
|
<q-tab name="fleet" icon="precision_manufacturing" label="Fleet"></q-tab>
|
||||||
<q-tab name="clients" icon="group" label="Clients" />
|
<q-tab name="clients" icon="group" label="Clients"></q-tab>
|
||||||
<q-tab name="deposits" icon="receipt_long" label="Deposits" />
|
<q-tab name="deposits" icon="receipt_long" label="Deposits"></q-tab>
|
||||||
<q-tab name="commission" icon="call_split" label="Commission" />
|
<q-tab name="commission" icon="call_split" label="Commission"></q-tab>
|
||||||
<q-tab name="worklist" icon="warning" label="Worklist">
|
<q-tab name="worklist" icon="warning" label="Worklist">
|
||||||
<q-badge
|
<q-badge
|
||||||
v-if="worklistCount > 0"
|
v-if="worklistCount > 0"
|
||||||
color="red" floating>${ worklistCount }
|
color="red" floating>${ worklistCount }
|
||||||
</q-badge>
|
</q-badge>
|
||||||
</q-tab>
|
</q-tab>
|
||||||
<q-tab name="reports" icon="download" label="Reports" />
|
<q-tab name="reports" icon="download" label="Reports"></q-tab>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
<q-separator />
|
<q-separator ></q-separator>
|
||||||
|
|
||||||
<q-tab-panels v-model="activeTab" animated>
|
<q-tab-panels v-model="activeTab" animated>
|
||||||
|
|
||||||
|
|
@ -95,13 +95,13 @@
|
||||||
<q-btn
|
<q-btn
|
||||||
color="primary" icon="add"
|
color="primary" icon="add"
|
||||||
label="Add machine"
|
label="Add machine"
|
||||||
@click="openAddMachineDialog" />
|
@click="openAddMachineDialog"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="!machines.length" class="bg-blue-1 text-grey-9">
|
<q-banner v-if="!machines.length" class="bg-blue-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="info" color="blue" />
|
<q-icon name="info" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
You haven't registered any machines yet. Click <b>Add machine</b> to
|
You haven't registered any machines yet. Click <b>Add machine</b> to
|
||||||
register a bitSpire ATM by its Nostr npub.
|
register a bitSpire ATM by its Nostr npub.
|
||||||
|
|
@ -187,13 +187,13 @@
|
||||||
<q-btn color="primary" icon="person_add"
|
<q-btn color="primary" icon="person_add"
|
||||||
label="Register LP"
|
label="Register LP"
|
||||||
:disable="!machines.length"
|
:disable="!machines.length"
|
||||||
@click="openAddClientDialog" />
|
@click="openAddClientDialog"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="!machines.length" class="bg-orange-1 text-grey-9">
|
<q-banner v-if="!machines.length" class="bg-orange-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="warning" color="orange" />
|
<q-icon name="warning" color="orange"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
Register at least one machine before adding LPs — an LP is scoped
|
Register at least one machine before adding LPs — an LP is scoped
|
||||||
to a specific machine.
|
to a specific machine.
|
||||||
|
|
@ -201,7 +201,7 @@
|
||||||
|
|
||||||
<q-banner v-else-if="!clients.length" class="bg-blue-1 text-grey-9">
|
<q-banner v-else-if="!clients.length" class="bg-blue-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="info" color="blue" />
|
<q-icon name="info" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
No LPs yet. Use <b>Register LP</b> to add one at any of your machines.
|
No LPs yet. Use <b>Register LP</b> to add one at any of your machines.
|
||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
@ -228,7 +228,7 @@
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td key="dca_mode">
|
<q-td key="dca_mode">
|
||||||
<q-badge :color="props.row.dca_mode === 'flow' ? 'blue' : 'purple'"
|
<q-badge :color="props.row.dca_mode === 'flow' ? 'blue' : 'purple'"
|
||||||
:label="props.row.dca_mode" />
|
:label="props.row.dca_mode"></q-badge>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td key="remaining_balance" class="text-right">
|
<q-td key="remaining_balance" class="text-right">
|
||||||
<span v-if="clientBalances[props.row.id]"
|
<span v-if="clientBalances[props.row.id]"
|
||||||
|
|
@ -251,27 +251,27 @@
|
||||||
<q-td key="status">
|
<q-td key="status">
|
||||||
<q-badge
|
<q-badge
|
||||||
:color="props.row.status === 'active' ? 'green' : 'grey'"
|
:color="props.row.status === 'active' ? 'green' : 'grey'"
|
||||||
:label="props.row.status" />
|
:label="props.row.status"></q-badge>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td key="actions" auto-width>
|
<q-td key="actions" auto-width>
|
||||||
<q-btn-dropdown flat dense size="sm" icon="more_vert">
|
<q-btn-dropdown flat dense size="sm" icon="more_vert">
|
||||||
<q-list dense>
|
<q-list dense>
|
||||||
<q-item clickable v-close-popup
|
<q-item clickable v-close-popup
|
||||||
@click="openEditClientDialog(props.row)">
|
@click="openEditClientDialog(props.row)">
|
||||||
<q-item-section avatar><q-icon name="edit" /></q-item-section>
|
<q-item-section avatar><q-icon name="edit"></q-icon></q-item-section>
|
||||||
<q-item-section>Edit</q-item-section>
|
<q-item-section>Edit</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-item clickable v-close-popup
|
<q-item clickable v-close-popup
|
||||||
@click="openSettleBalanceDialog(props.row)">
|
@click="openSettleBalanceDialog(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="payments" color="primary" />
|
<q-icon name="payments" color="primary"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Settle balance…</q-item-section>
|
<q-item-section>Settle balance…</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-item clickable v-close-popup
|
<q-item clickable v-close-popup
|
||||||
@click="confirmDeleteClient(props.row)">
|
@click="confirmDeleteClient(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="delete" color="red-7" />
|
<q-icon name="delete" color="red-7"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Delete</q-item-section>
|
<q-item-section>Delete</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -295,7 +295,7 @@
|
||||||
<q-btn color="primary" icon="add"
|
<q-btn color="primary" icon="add"
|
||||||
label="Record deposit"
|
label="Record deposit"
|
||||||
:disable="!clients.length"
|
:disable="!clients.length"
|
||||||
@click="openAddDepositDialog" />
|
@click="openAddDepositDialog"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -307,18 +307,18 @@
|
||||||
{label: 'Pending', value: 'pending'},
|
{label: 'Pending', value: 'pending'},
|
||||||
{label: 'Confirmed', value: 'confirmed'},
|
{label: 'Confirmed', value: 'confirmed'},
|
||||||
{label: 'Rejected', value: 'rejected'}]"
|
{label: 'Rejected', value: 'rejected'}]"
|
||||||
label="Status" emit-value map-options dense outlined />
|
label="Status" emit-value map-options dense outlined></q-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
<q-select v-model="depositsFilter.client_id"
|
<q-select v-model="depositsFilter.client_id"
|
||||||
:options="depositClientOptions"
|
:options="depositClientOptions"
|
||||||
label="LP" emit-value map-options dense outlined clearable />
|
label="LP" emit-value map-options dense outlined clearable></q-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="!clients.length" class="bg-orange-1 text-grey-9">
|
<q-banner v-if="!clients.length" class="bg-orange-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="warning" color="orange" />
|
<q-icon name="warning" color="orange"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
Register at least one LP before recording deposits.
|
Register at least one LP before recording deposits.
|
||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
@ -326,7 +326,7 @@
|
||||||
<q-banner v-else-if="!filteredDeposits.length && !deposits.length"
|
<q-banner v-else-if="!filteredDeposits.length && !deposits.length"
|
||||||
class="bg-blue-1 text-grey-9">
|
class="bg-blue-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="info" color="blue" />
|
<q-icon name="info" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
No deposits yet. Use <b>Record deposit</b> to log a new one.
|
No deposits yet. Use <b>Record deposit</b> to log a new one.
|
||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
@ -347,7 +347,7 @@
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td key="status">
|
<q-td key="status">
|
||||||
<q-badge :color="depositStatusColor(props.row.status)"
|
<q-badge :color="depositStatusColor(props.row.status)"
|
||||||
:label="props.row.status" />
|
:label="props.row.status"></q-badge>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td key="client">
|
<q-td key="client">
|
||||||
<span v-text="clientUsernameById(props.row.client_id)"></span>
|
<span v-text="clientUsernameById(props.row.client_id)"></span>
|
||||||
|
|
@ -381,7 +381,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="confirmDepositStatus(props.row, 'confirmed')">
|
@click="confirmDepositStatus(props.row, 'confirmed')">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="check_circle" color="green" />
|
<q-icon name="check_circle" color="green"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Confirm</q-item-section>
|
<q-item-section>Confirm</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -389,7 +389,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="openRejectDepositDialog(props.row)">
|
@click="openRejectDepositDialog(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="cancel" color="red" />
|
<q-icon name="cancel" color="red"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Reject…</q-item-section>
|
<q-item-section>Reject…</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -397,7 +397,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="openEditDepositDialog(props.row)">
|
@click="openEditDepositDialog(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="edit" />
|
<q-icon name="edit"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Edit</q-item-section>
|
<q-item-section>Edit</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -405,7 +405,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="confirmDeleteDeposit(props.row)">
|
@click="confirmDeleteDeposit(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="delete" color="red-7" />
|
<q-icon name="delete" color="red-7"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Delete</q-item-section>
|
<q-item-section>Delete</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -435,7 +435,7 @@
|
||||||
label="Scope being edited"
|
label="Scope being edited"
|
||||||
emit-value map-options
|
emit-value map-options
|
||||||
dense outlined
|
dense outlined
|
||||||
@update:model-value="loadCommissionSplits" />
|
@update:model-value="loadCommissionSplits"></q-select>
|
||||||
<div class="text-caption q-mt-xs" :style="{opacity: 0.7}">
|
<div class="text-caption q-mt-xs" :style="{opacity: 0.7}">
|
||||||
<span v-if="commissionScope === null">
|
<span v-if="commissionScope === null">
|
||||||
Default ruleset — applies to every machine without an
|
Default ruleset — applies to every machine without an
|
||||||
|
|
@ -464,7 +464,7 @@
|
||||||
v-text="(commissionSum * 100).toFixed(2) + '%'"></span>
|
v-text="(commissionSum * 100).toFixed(2) + '%'"></span>
|
||||||
<q-icon v-if="commissionSumValid"
|
<q-icon v-if="commissionSumValid"
|
||||||
name="check_circle" color="green" size="xs"
|
name="check_circle" color="green" size="xs"
|
||||||
class="q-ml-xs" />
|
class="q-ml-xs"></q-icon>
|
||||||
<q-icon v-else
|
<q-icon v-else
|
||||||
name="error" color="red" size="xs"
|
name="error" color="red" size="xs"
|
||||||
class="q-ml-xs">
|
class="q-ml-xs">
|
||||||
|
|
@ -475,14 +475,14 @@
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<q-btn flat dense color="primary" icon="add"
|
<q-btn flat dense color="primary" icon="add"
|
||||||
label="Add leg"
|
label="Add leg"
|
||||||
@click="addCommissionLeg" />
|
@click="addCommissionLeg"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="!commissionLegs.length"
|
<q-banner v-if="!commissionLegs.length"
|
||||||
class="bg-blue-1 text-grey-9">
|
class="bg-blue-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="info" color="blue" />
|
<q-icon name="info" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
<span v-if="commissionScope === null">
|
<span v-if="commissionScope === null">
|
||||||
No default rules. Without a default, all operator
|
No default rules. Without a default, all operator
|
||||||
|
|
@ -499,12 +499,12 @@
|
||||||
<q-select v-model="leg.wallet_id"
|
<q-select v-model="leg.wallet_id"
|
||||||
:options="walletOptions"
|
:options="walletOptions"
|
||||||
label="Wallet"
|
label="Wallet"
|
||||||
emit-value map-options dense outlined />
|
emit-value map-options dense outlined></q-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-7 col-md-4">
|
<div class="col-7 col-md-4">
|
||||||
<q-input v-model="leg.label"
|
<q-input v-model="leg.label"
|
||||||
label="Label (e.g. employee, maintenance)"
|
label="Label (e.g. employee, maintenance)"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 col-md-3">
|
<div class="col-4 col-md-3">
|
||||||
<q-input v-model.number="leg.pct"
|
<q-input v-model.number="leg.pct"
|
||||||
|
|
@ -519,13 +519,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1 col-md-1">
|
<div class="col-1 col-md-1">
|
||||||
<q-btn flat dense round icon="delete" color="red-7"
|
<q-btn flat dense round icon="delete" color="red-7"
|
||||||
@click="commissionLegs.splice(idx, 1)" />
|
@click="commissionLegs.splice(idx, 1)"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="commissionPreview" class="bg-grey-2 text-grey-9 q-mt-md">
|
<q-banner v-if="commissionPreview" class="bg-grey-2 text-grey-9 q-mt-md">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="visibility" color="grey" />
|
<q-icon name="visibility" color="grey"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
Preview against
|
Preview against
|
||||||
<b v-text="formatSats(commissionPreviewInput)"></b>
|
<b v-text="formatSats(commissionPreviewInput)"></b>
|
||||||
|
|
@ -543,15 +543,15 @@
|
||||||
<q-btn v-if="commissionScope !== null && commissionLegs.length"
|
<q-btn v-if="commissionScope !== null && commissionLegs.length"
|
||||||
flat color="red"
|
flat color="red"
|
||||||
label="Remove override"
|
label="Remove override"
|
||||||
@click="confirmDeleteCommissionOverride" />
|
@click="confirmDeleteCommissionOverride"></q-btn>
|
||||||
<q-btn flat label="Reload"
|
<q-btn flat label="Reload"
|
||||||
:disable="commissionSaving"
|
:disable="commissionSaving"
|
||||||
@click="loadCommissionSplits" />
|
@click="loadCommissionSplits"></q-btn>
|
||||||
<q-btn color="primary"
|
<q-btn color="primary"
|
||||||
label="Save"
|
label="Save"
|
||||||
:disable="!commissionSumValid"
|
:disable="!commissionSumValid"
|
||||||
:loading="commissionSaving"
|
:loading="commissionSaving"
|
||||||
@click="saveCommissionSplits" />
|
@click="saveCommissionSplits"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
|
@ -569,17 +569,17 @@
|
||||||
<q-input v-model.number="worklistThreshold"
|
<q-input v-model.number="worklistThreshold"
|
||||||
label="Threshold (min)" dense outlined
|
label="Threshold (min)" dense outlined
|
||||||
:style="{width: '120px'}"
|
:style="{width: '120px'}"
|
||||||
type="number" min="1" />
|
type="number" min="1"></q-input>
|
||||||
<q-btn flat dense color="primary" icon="refresh"
|
<q-btn flat dense color="primary" icon="refresh"
|
||||||
:loading="worklistLoading"
|
:loading="worklistLoading"
|
||||||
@click="loadWorklist" />
|
@click="loadWorklist"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-banner v-if="worklist.totalCount === 0"
|
<q-banner v-if="worklist.totalCount === 0"
|
||||||
class="bg-green-1 text-grey-9">
|
class="bg-green-1 text-grey-9">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="check_circle" color="green" />
|
<q-icon name="check_circle" color="green"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
All clear — no errored or stuck settlements.
|
All clear — no errored or stuck settlements.
|
||||||
</q-banner>
|
</q-banner>
|
||||||
|
|
@ -589,7 +589,7 @@
|
||||||
class="q-mb-lg">
|
class="q-mb-lg">
|
||||||
<div class="row items-center q-mb-sm">
|
<div class="row items-center q-mb-sm">
|
||||||
<q-icon :name="bucket.icon" :color="bucket.color" size="sm"
|
<q-icon :name="bucket.icon" :color="bucket.color" size="sm"
|
||||||
class="q-mr-sm" />
|
class="q-mr-sm"></q-icon>
|
||||||
<span :style="{fontWeight: 500}" v-text="bucket.label"></span>
|
<span :style="{fontWeight: 500}" v-text="bucket.label"></span>
|
||||||
<q-chip dense
|
<q-chip dense
|
||||||
:color="bucket.color" text-color="white"
|
:color="bucket.color" text-color="white"
|
||||||
|
|
@ -666,7 +666,7 @@
|
||||||
<q-card-actions>
|
<q-card-actions>
|
||||||
<q-btn flat color="primary" icon="download"
|
<q-btn flat color="primary" icon="download"
|
||||||
label="machines.csv"
|
label="machines.csv"
|
||||||
@click="downloadMachinesCsv" />
|
@click="downloadMachinesCsv"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -681,7 +681,7 @@
|
||||||
<q-card-actions>
|
<q-card-actions>
|
||||||
<q-btn flat color="primary" icon="download"
|
<q-btn flat color="primary" icon="download"
|
||||||
label="clients.csv"
|
label="clients.csv"
|
||||||
@click="downloadClientsCsv" />
|
@click="downloadClientsCsv"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -696,7 +696,7 @@
|
||||||
<q-card-actions>
|
<q-card-actions>
|
||||||
<q-btn flat color="primary" icon="download"
|
<q-btn flat color="primary" icon="download"
|
||||||
label="deposits.csv"
|
label="deposits.csv"
|
||||||
@click="downloadDepositsCsv" />
|
@click="downloadDepositsCsv"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -712,7 +712,7 @@
|
||||||
<q-btn flat color="primary" icon="download"
|
<q-btn flat color="primary" icon="download"
|
||||||
label="payments.csv"
|
label="payments.csv"
|
||||||
:loading="reportsBusy"
|
:loading="reportsBusy"
|
||||||
@click="downloadPaymentsCsv" />
|
@click="downloadPaymentsCsv"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -729,8 +729,8 @@
|
||||||
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Add bitSpire machine</div>
|
<div class="text-h6">Add bitSpire machine</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p class="text-caption q-mb-md" :style="{opacity: 0.7}">
|
<p class="text-caption q-mb-md" :style="{opacity: 0.7}">
|
||||||
|
|
@ -744,14 +744,14 @@
|
||||||
label="Machine name"
|
label="Machine name"
|
||||||
hint="Operator-friendly label (e.g. ATM-Antigua-1)"
|
hint="Operator-friendly label (e.g. ATM-Antigua-1)"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
v-model="addMachineDialog.data.location"
|
v-model="addMachineDialog.data.location"
|
||||||
label="Location (optional)"
|
label="Location (optional)"
|
||||||
hint="Physical address or city; shown on operator dashboard"
|
hint="Physical address or city; shown on operator dashboard"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
v-model="addMachineDialog.data.machine_npub"
|
v-model="addMachineDialog.data.machine_npub"
|
||||||
|
|
@ -779,21 +779,21 @@
|
||||||
hint="Only used if bitSpire doesn't supply a per-tx split (lamassu-next#44)."
|
hint="Only used if bitSpire doesn't supply a per-tx split (lamassu-next#44)."
|
||||||
type="number" step="0.0001" min="0" max="1"
|
type="number" step="0.0001" min="0" max="1"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
v-model="addMachineDialog.data.fiat_code"
|
v-model="addMachineDialog.data.fiat_code"
|
||||||
label="Fiat code"
|
label="Fiat code"
|
||||||
hint="Currency the ATM dispenses (GTQ / USD / MXN / etc.)"
|
hint="Currency the ATM dispenses (GTQ / USD / MXN / etc.)"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right" class="text-primary">
|
<q-card-actions align="right" class="text-primary">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
color="primary" label="Add machine"
|
color="primary" label="Add machine"
|
||||||
:loading="addMachineDialog.saving"
|
:loading="addMachineDialog.saving"
|
||||||
@click="submitAddMachine" />
|
@click="submitAddMachine"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -809,7 +809,7 @@
|
||||||
v-text="machineDetail.machine.name || 'Unnamed machine'"></div>
|
v-text="machineDetail.machine.name || 'Unnamed machine'"></div>
|
||||||
<q-chip dense color="white" text-color="primary"
|
<q-chip dense color="white" text-color="primary"
|
||||||
v-text="machineDetail.machine.fiat_code"></q-chip>
|
v-text="machineDetail.machine.fiat_code"></q-chip>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn flat dense round icon="refresh"
|
<q-btn flat dense round icon="refresh"
|
||||||
@click="reloadMachineDetail"
|
@click="reloadMachineDetail"
|
||||||
:loading="machineDetail.loading">
|
:loading="machineDetail.loading">
|
||||||
|
|
@ -844,7 +844,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-separator class="q-mb-md" />
|
<q-separator class="q-mb-md"></q-separator>
|
||||||
|
|
||||||
<div class="row items-center q-mb-sm">
|
<div class="row items-center q-mb-sm">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|
@ -873,7 +873,7 @@
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-td key="status">
|
<q-td key="status">
|
||||||
<q-badge :color="settlementStatusColor(props.row.status)"
|
<q-badge :color="settlementStatusColor(props.row.status)"
|
||||||
:label="props.row.status" />
|
:label="props.row.status"></q-badge>
|
||||||
<q-icon v-if="props.row.used_fallback_split"
|
<q-icon v-if="props.row.used_fallback_split"
|
||||||
name="warning_amber" color="orange" size="sm"
|
name="warning_amber" color="orange" size="sm"
|
||||||
class="q-ml-xs">
|
class="q-ml-xs">
|
||||||
|
|
@ -915,7 +915,7 @@
|
||||||
<q-item clickable v-close-popup
|
<q-item clickable v-close-popup
|
||||||
@click="openSettlementNote(props.row)">
|
@click="openSettlementNote(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="edit_note" />
|
<q-icon name="edit_note"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Add note</q-item-section>
|
<q-item-section>Add note</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -923,7 +923,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="confirmRetrySettlement(props.row)">
|
@click="confirmRetrySettlement(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="restart_alt" color="primary" />
|
<q-icon name="restart_alt" color="primary"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Retry distribution</q-item-section>
|
<q-item-section>Retry distribution</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -932,7 +932,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="openPartialDispense(props.row)">
|
@click="openPartialDispense(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="precision_manufacturing" color="warning" />
|
<q-icon name="precision_manufacturing" color="warning"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Partial dispense…</q-item-section>
|
<q-item-section>Partial dispense…</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -941,7 +941,7 @@
|
||||||
clickable v-close-popup
|
clickable v-close-popup
|
||||||
@click="confirmForceReset(props.row)">
|
@click="confirmForceReset(props.row)">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-icon name="local_fire_department" color="red" />
|
<q-icon name="local_fire_department" color="red"></q-icon>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>Force-reset (stuck)…</q-item-section>
|
<q-item-section>Force-reset (stuck)…</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -968,13 +968,13 @@
|
||||||
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Apply partial dispense</div>
|
<div class="text-h6">Apply partial dispense</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section v-if="partialDispenseDialog.settlement">
|
<q-card-section v-if="partialDispenseDialog.settlement">
|
||||||
<q-banner class="bg-blue-1 text-grey-9 q-mb-md">
|
<q-banner class="bg-blue-1 text-grey-9 q-mb-md">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="info" color="blue" />
|
<q-icon name="info" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
Original gross:
|
Original gross:
|
||||||
<b v-text="formatSats(partialDispenseDialog.settlement.gross_sats)"></b>.
|
<b v-text="formatSats(partialDispenseDialog.settlement.gross_sats)"></b>.
|
||||||
|
|
@ -984,8 +984,8 @@
|
||||||
<q-tabs v-model="partialDispenseDialog.mode" dense
|
<q-tabs v-model="partialDispenseDialog.mode" dense
|
||||||
active-color="primary" indicator-color="primary"
|
active-color="primary" indicator-color="primary"
|
||||||
align="justify">
|
align="justify">
|
||||||
<q-tab name="fraction" label="By fraction (0..1)" />
|
<q-tab name="fraction" label="By fraction (0..1)"></q-tab>
|
||||||
<q-tab name="sats" label="By exact sats" />
|
<q-tab name="sats" label="By exact sats"></q-tab>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
<q-tab-panels v-model="partialDispenseDialog.mode" animated>
|
<q-tab-panels v-model="partialDispenseDialog.mode" animated>
|
||||||
<q-tab-panel name="fraction" class="q-pa-sm">
|
<q-tab-panel name="fraction" class="q-pa-sm">
|
||||||
|
|
@ -993,7 +993,7 @@
|
||||||
label="Dispensed fraction"
|
label="Dispensed fraction"
|
||||||
hint="e.g. 0.6 means 60% of the original tx was dispensed"
|
hint="e.g. 0.6 means 60% of the original tx was dispensed"
|
||||||
type="number" step="0.01" min="0" max="1"
|
type="number" step="0.01" min="0" max="1"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="sats" class="q-pa-sm">
|
<q-tab-panel name="sats" class="q-pa-sm">
|
||||||
<q-input v-model.number="partialDispenseDialog.dispensed_sats"
|
<q-input v-model.number="partialDispenseDialog.dispensed_sats"
|
||||||
|
|
@ -1001,21 +1001,21 @@
|
||||||
hint="Exact sat amount actually dispensed (≤ original gross)"
|
hint="Exact sat amount actually dispensed (≤ original gross)"
|
||||||
type="number" step="1" min="0"
|
type="number" step="1" min="0"
|
||||||
:max="partialDispenseDialog.settlement.gross_sats"
|
:max="partialDispenseDialog.settlement.gross_sats"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
<q-input v-model="partialDispenseDialog.notes"
|
<q-input v-model="partialDispenseDialog.notes"
|
||||||
label="Reason (recorded in audit memo)"
|
label="Reason (recorded in audit memo)"
|
||||||
type="textarea" autogrow
|
type="textarea" autogrow
|
||||||
class="q-mt-md"
|
class="q-mt-md"
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="warning"
|
<q-btn color="warning"
|
||||||
label="Apply partial dispense"
|
label="Apply partial dispense"
|
||||||
:loading="partialDispenseDialog.saving"
|
:loading="partialDispenseDialog.saving"
|
||||||
@click="submitPartialDispense" />
|
@click="submitPartialDispense"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1027,8 +1027,8 @@
|
||||||
<q-card :style="{minWidth: '420px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '420px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Add note to settlement</div>
|
<div class="text-h6">Add note to settlement</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p class="text-caption q-mb-sm" :style="{opacity: 0.7}">
|
<p class="text-caption q-mb-sm" :style="{opacity: 0.7}">
|
||||||
|
|
@ -1042,10 +1042,10 @@
|
||||||
dense outlined />
|
dense outlined />
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="primary" label="Save note"
|
<q-btn color="primary" label="Save note"
|
||||||
:loading="noteDialog.saving"
|
:loading="noteDialog.saving"
|
||||||
@click="submitNote" />
|
@click="submitNote"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1057,8 +1057,8 @@
|
||||||
<q-card :style="{minWidth: '460px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '460px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Platform fee (super-only)</div>
|
<div class="text-h6">Platform fee (super-only)</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p class="text-caption q-mb-md" :style="{opacity: 0.7}">
|
<p class="text-caption q-mb-md" :style="{opacity: 0.7}">
|
||||||
|
|
@ -1070,17 +1070,17 @@
|
||||||
label="Fee % (decimal, 0..1)"
|
label="Fee % (decimal, 0..1)"
|
||||||
hint="0.30 = 30% of every operator's commission"
|
hint="0.30 = 30% of every operator's commission"
|
||||||
type="number" step="0.0001" min="0" max="1"
|
type="number" step="0.0001" min="0" max="1"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
<q-input v-model="superFeeDialog.data.super_fee_wallet_id"
|
<q-input v-model="superFeeDialog.data.super_fee_wallet_id"
|
||||||
label="Super fee destination wallet_id"
|
label="Super fee destination wallet_id"
|
||||||
hint="LNbits wallet that collects the platform fee"
|
hint="LNbits wallet that collects the platform fee"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="primary" label="Save"
|
<q-btn color="primary" label="Save"
|
||||||
:loading="superFeeDialog.saving"
|
:loading="superFeeDialog.saving"
|
||||||
@click="submitSuperFee" />
|
@click="submitSuperFee"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1093,8 +1093,8 @@
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6"
|
<div class="text-h6"
|
||||||
v-text="depositDialog.mode === 'add' ? 'Record deposit' : 'Edit deposit'"></div>
|
v-text="depositDialog.mode === 'add' ? 'Record deposit' : 'Edit deposit'"></div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-select v-if="depositDialog.mode === 'add'"
|
<q-select v-if="depositDialog.mode === 'add'"
|
||||||
|
|
@ -1113,19 +1113,19 @@
|
||||||
|
|
||||||
<q-input v-model="depositDialog.data.currency"
|
<q-input v-model="depositDialog.data.currency"
|
||||||
label="Currency"
|
label="Currency"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
|
|
||||||
<q-input v-model="depositDialog.data.notes"
|
<q-input v-model="depositDialog.data.notes"
|
||||||
label="Notes (optional)"
|
label="Notes (optional)"
|
||||||
type="textarea" autogrow
|
type="textarea" autogrow
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="primary"
|
<q-btn color="primary"
|
||||||
:label="depositDialog.mode === 'add' ? 'Record' : 'Save'"
|
:label="depositDialog.mode === 'add' ? 'Record' : 'Save'"
|
||||||
:loading="depositDialog.saving"
|
:loading="depositDialog.saving"
|
||||||
@click="submitDeposit" />
|
@click="submitDeposit"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1137,8 +1137,8 @@
|
||||||
<q-card :style="{minWidth: '420px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '420px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Reject deposit</div>
|
<div class="text-h6">Reject deposit</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p class="text-caption q-mb-sm" :style="{opacity: 0.7}">
|
<p class="text-caption q-mb-sm" :style="{opacity: 0.7}">
|
||||||
|
|
@ -1148,13 +1148,13 @@
|
||||||
<q-input v-model="rejectDepositDialog.notes"
|
<q-input v-model="rejectDepositDialog.notes"
|
||||||
label="Reason (optional)"
|
label="Reason (optional)"
|
||||||
type="textarea" autogrow
|
type="textarea" autogrow
|
||||||
dense outlined />
|
dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="red" label="Reject"
|
<q-btn color="red" label="Reject"
|
||||||
:loading="rejectDepositDialog.saving"
|
:loading="rejectDepositDialog.saving"
|
||||||
@click="submitRejectDeposit" />
|
@click="submitRejectDeposit"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1166,8 +1166,8 @@
|
||||||
<q-card :style="{minWidth: '520px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '520px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6" v-text="clientDialog.mode === 'add' ? 'Register liquidity provider' : 'Edit LP'"></div>
|
<div class="text-h6" v-text="clientDialog.mode === 'add' ? 'Register liquidity provider' : 'Edit LP'"></div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p class="text-caption q-mb-md" :style="{opacity: 0.7}"
|
<p class="text-caption q-mb-md" :style="{opacity: 0.7}"
|
||||||
|
|
@ -1203,43 +1203,43 @@
|
||||||
|
|
||||||
<q-input v-model="clientDialog.data.username"
|
<q-input v-model="clientDialog.data.username"
|
||||||
label="Display name (optional)"
|
label="Display name (optional)"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
|
|
||||||
<q-select v-model="clientDialog.data.dca_mode"
|
<q-select v-model="clientDialog.data.dca_mode"
|
||||||
:options="[{label: 'Flow (proportional)', value: 'flow'},
|
:options="[{label: 'Flow (proportional)', value: 'flow'},
|
||||||
{label: 'Fixed (daily limit)', value: 'fixed'}]"
|
{label: 'Fixed (daily limit)', value: 'fixed'}]"
|
||||||
label="DCA mode"
|
label="DCA mode"
|
||||||
emit-value map-options
|
emit-value map-options
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-select>
|
||||||
|
|
||||||
<q-input v-if="clientDialog.data.dca_mode === 'fixed'"
|
<q-input v-if="clientDialog.data.dca_mode === 'fixed'"
|
||||||
v-model.number="clientDialog.data.fixed_mode_daily_limit"
|
v-model.number="clientDialog.data.fixed_mode_daily_limit"
|
||||||
label="Fixed mode daily limit (fiat)"
|
label="Fixed mode daily limit (fiat)"
|
||||||
type="number" step="0.01"
|
type="number" step="0.01"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
|
|
||||||
<q-toggle v-model="clientDialog.data.autoforward_enabled"
|
<q-toggle v-model="clientDialog.data.autoforward_enabled"
|
||||||
label="Auto-forward DCA to external LN address"
|
label="Auto-forward DCA to external LN address"
|
||||||
class="q-mb-md" />
|
class="q-mb-md"></q-toggle>
|
||||||
|
|
||||||
<q-input v-if="clientDialog.data.autoforward_enabled"
|
<q-input v-if="clientDialog.data.autoforward_enabled"
|
||||||
v-model="clientDialog.data.autoforward_ln_address"
|
v-model="clientDialog.data.autoforward_ln_address"
|
||||||
label="LN address (e.g. user@walletofsatoshi.com)"
|
label="LN address (e.g. user@walletofsatoshi.com)"
|
||||||
hint="LP-controlled; failures leave sats safely in LP's LNbits wallet"
|
hint="LP-controlled; failures leave sats safely in LP's LNbits wallet"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
|
|
||||||
<q-select v-if="clientDialog.mode === 'edit'"
|
<q-select v-if="clientDialog.mode === 'edit'"
|
||||||
v-model="clientDialog.data.status"
|
v-model="clientDialog.data.status"
|
||||||
:options="['active', 'paused', 'closed']"
|
:options="['active', 'paused', 'closed']"
|
||||||
label="Status"
|
label="Status"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-select>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="primary"
|
<q-btn color="primary"
|
||||||
:label="clientDialog.mode === 'add' ? 'Register' : 'Save'"
|
:label="clientDialog.mode === 'add' ? 'Register' : 'Save'"
|
||||||
:loading="clientDialog.saving"
|
:loading="clientDialog.saving"
|
||||||
@click="submitClient" />
|
@click="submitClient"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1251,13 +1251,13 @@
|
||||||
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Settle LP balance</div>
|
<div class="text-h6">Settle LP balance</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section v-if="settleBalanceDialog.client">
|
<q-card-section v-if="settleBalanceDialog.client">
|
||||||
<q-banner class="bg-blue-1 text-grey-9 q-mb-md">
|
<q-banner class="bg-blue-1 text-grey-9 q-mb-md">
|
||||||
<template v-slot:avatar>
|
<template v-slot:avatar>
|
||||||
<q-icon name="payments" color="blue" />
|
<q-icon name="payments" color="blue"></q-icon>
|
||||||
</template>
|
</template>
|
||||||
Pay the LP's remaining fiat balance in sats from your wallet at the
|
Pay the LP's remaining fiat balance in sats from your wallet at the
|
||||||
rate you choose. Useful to zero out small balances that would
|
rate you choose. Useful to zero out small balances that would
|
||||||
|
|
@ -1287,18 +1287,18 @@
|
||||||
<q-input v-model.number="settleBalanceDialog.data.amount_fiat"
|
<q-input v-model.number="settleBalanceDialog.data.amount_fiat"
|
||||||
label="Amount (fiat) — leave blank to settle full remaining"
|
label="Amount (fiat) — leave blank to settle full remaining"
|
||||||
type="number" step="0.01"
|
type="number" step="0.01"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
|
|
||||||
<q-input v-model="settleBalanceDialog.data.notes"
|
<q-input v-model="settleBalanceDialog.data.notes"
|
||||||
label="Notes (optional, audit memo)"
|
label="Notes (optional, audit memo)"
|
||||||
type="textarea" autogrow
|
type="textarea" autogrow
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn color="primary" label="Settle balance"
|
<q-btn color="primary" label="Settle balance"
|
||||||
:loading="settleBalanceDialog.saving"
|
:loading="settleBalanceDialog.saving"
|
||||||
@click="submitSettleBalance" />
|
@click="submitSettleBalance"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -1310,36 +1310,36 @@
|
||||||
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
||||||
<q-card-section class="row items-center q-pb-none">
|
<q-card-section class="row items-center q-pb-none">
|
||||||
<div class="text-h6">Edit machine</div>
|
<div class="text-h6">Edit machine</div>
|
||||||
<q-space />
|
<q-space ></q-space>
|
||||||
<q-btn icon="close" flat round dense v-close-popup />
|
<q-btn icon="close" flat round dense v-close-popup></q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-input v-model="editMachineDialog.data.name"
|
<q-input v-model="editMachineDialog.data.name"
|
||||||
label="Machine name" class="q-mb-md" dense outlined />
|
label="Machine name" class="q-mb-md" dense outlined></q-input>
|
||||||
<q-input v-model="editMachineDialog.data.location"
|
<q-input v-model="editMachineDialog.data.location"
|
||||||
label="Location" class="q-mb-md" dense outlined />
|
label="Location" class="q-mb-md" dense outlined></q-input>
|
||||||
<q-select
|
<q-select
|
||||||
v-model="editMachineDialog.data.wallet_id"
|
v-model="editMachineDialog.data.wallet_id"
|
||||||
:options="walletOptions"
|
:options="walletOptions"
|
||||||
label="Wallet"
|
label="Wallet"
|
||||||
emit-value map-options
|
emit-value map-options
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
dense outlined />
|
dense outlined></q-select>
|
||||||
<q-input v-model.number="editMachineDialog.data.fallback_commission_pct"
|
<q-input v-model.number="editMachineDialog.data.fallback_commission_pct"
|
||||||
label="Fallback commission %"
|
label="Fallback commission %"
|
||||||
type="number" step="0.0001" min="0" max="1"
|
type="number" step="0.0001" min="0" max="1"
|
||||||
class="q-mb-md" dense outlined />
|
class="q-mb-md" dense outlined></q-input>
|
||||||
<q-input v-model="editMachineDialog.data.fiat_code"
|
<q-input v-model="editMachineDialog.data.fiat_code"
|
||||||
label="Fiat code" class="q-mb-md" dense outlined />
|
label="Fiat code" class="q-mb-md" dense outlined></q-input>
|
||||||
<q-toggle v-model="editMachineDialog.data.is_active"
|
<q-toggle v-model="editMachineDialog.data.is_active"
|
||||||
label="Active (receives settlements)" class="q-mb-md" />
|
label="Active (receives settlements)" class="q-mb-md"></q-toggle>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" v-close-popup />
|
<q-btn flat label="Cancel" v-close-popup></q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
color="primary" label="Save"
|
color="primary" label="Save"
|
||||||
:loading="editMachineDialog.saving"
|
:loading="editMachineDialog.saving"
|
||||||
@click="submitEditMachine" />
|
@click="submitEditMachine"></q-btn>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue