Revert "Improve configuration form for readability and UX"
This commit is contained in:
parent
771427a0b2
commit
93ba3ba628
12 changed files with 512 additions and 552 deletions
|
|
@ -1,7 +1,7 @@
|
|||
window.app = Vue.createApp({
|
||||
el: '#vue',
|
||||
el: "#vue",
|
||||
mixins: [windowMixin],
|
||||
delimiters: ['${', '}'],
|
||||
delimiters: ["${", "}"],
|
||||
data: function () {
|
||||
return {
|
||||
selectedWallet: null,
|
||||
|
|
@ -10,244 +10,244 @@ window.app = Vue.createApp({
|
|||
nwcsTable: {
|
||||
columns: [
|
||||
{
|
||||
name: 'description',
|
||||
align: 'left',
|
||||
label: 'Description',
|
||||
field: 'description'
|
||||
name: "description",
|
||||
align: "left",
|
||||
label: "Description",
|
||||
field: "description",
|
||||
},
|
||||
{name: 'status', align: 'left', label: 'Status', field: 'status'},
|
||||
{ name: "status", align: "left", label: "Status", field: "status" },
|
||||
{
|
||||
name: 'last_used',
|
||||
align: 'left',
|
||||
label: 'Last used',
|
||||
field: 'last_used'
|
||||
name: "last_used",
|
||||
align: "left",
|
||||
label: "Last used",
|
||||
field: "last_used",
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
align: 'left',
|
||||
label: 'Created',
|
||||
field: 'created_at'
|
||||
name: "created_at",
|
||||
align: "left",
|
||||
label: "Created",
|
||||
field: "created_at",
|
||||
},
|
||||
{
|
||||
name: 'expires_at',
|
||||
align: 'left',
|
||||
label: 'Expires',
|
||||
field: 'expires_at'
|
||||
}
|
||||
name: "expires_at",
|
||||
align: "left",
|
||||
label: "Expires",
|
||||
field: "expires_at",
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 10
|
||||
}
|
||||
rowsPerPage: 10,
|
||||
},
|
||||
},
|
||||
connectDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
data: {},
|
||||
},
|
||||
pairingDialog: {
|
||||
show: false,
|
||||
data: {
|
||||
pairingUrl: ''
|
||||
}
|
||||
pairingUrl: "",
|
||||
},
|
||||
},
|
||||
pairingQrDialog: {
|
||||
show: false,
|
||||
data: {
|
||||
pairingUrl: ''
|
||||
}
|
||||
pairingUrl: "",
|
||||
},
|
||||
},
|
||||
connectionInfoDialog: {
|
||||
show: false,
|
||||
data: {}
|
||||
}
|
||||
}
|
||||
data: {},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
showConnectDialog() {
|
||||
const wallet = this.getWallet()
|
||||
const wallet = this.getWallet();
|
||||
if (!wallet) {
|
||||
Quasar.Notify.create({
|
||||
type: 'negative',
|
||||
message: 'Please select a wallet first'
|
||||
})
|
||||
return
|
||||
type: "negative",
|
||||
message: "Please select a wallet first",
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
this.connectDialog.show = true
|
||||
this.connectDialog.show = true;
|
||||
}
|
||||
},
|
||||
openConnectionInfoDialog(data) {
|
||||
this.connectionInfoDialog.data = data
|
||||
this.connectionInfoDialog.show = true
|
||||
this.connectionInfoDialog.data = data;
|
||||
this.connectionInfoDialog.show = true;
|
||||
},
|
||||
closeConnectionInfoDialog() {
|
||||
this.connectionInfoDialog.show = false
|
||||
this.connectionInfoDialog.show = false;
|
||||
},
|
||||
openPairingUrl() {
|
||||
const url = this.pairingDialog.data.pairingUrl
|
||||
if (url) window.open(url, '_blank')
|
||||
const url = this.pairingDialog.data.pairingUrl;
|
||||
if (url) window.open(url, "_blank");
|
||||
},
|
||||
go(url) {
|
||||
window.open(url, '_blank')
|
||||
window.open(url, "_blank");
|
||||
},
|
||||
async copyPairingUrl() {
|
||||
const url = this.pairingDialog.data.pairingUrl
|
||||
const url = this.pairingDialog.data.pairingUrl;
|
||||
if (url) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(url)
|
||||
await navigator.clipboard.writeText(url);
|
||||
Quasar.Notify.create({
|
||||
type: 'positive',
|
||||
message: 'URL copied to clipboard'
|
||||
})
|
||||
type: "positive",
|
||||
message: "URL copied to clipboard",
|
||||
});
|
||||
} catch (err) {
|
||||
Quasar.Notify.create({
|
||||
type: 'negative',
|
||||
message: 'Failed to copy URL.'
|
||||
})
|
||||
type: "negative",
|
||||
message: "Failed to copy URL.",
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
showPairingQR() {
|
||||
this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl
|
||||
this.pairingQrDialog.show = true
|
||||
this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl;
|
||||
this.pairingQrDialog.show = true;
|
||||
},
|
||||
closePairingQrDialog() {
|
||||
this.pairingQrDialog.show = false
|
||||
this.pairingQrDialog.show = false;
|
||||
},
|
||||
loadConnectDialogData() {
|
||||
this.connectDialog.data = {
|
||||
description: '',
|
||||
description: "",
|
||||
expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7,
|
||||
neverExpires: true,
|
||||
permissions: [],
|
||||
budgets: []
|
||||
}
|
||||
budgets: [],
|
||||
};
|
||||
for (const permission of this.nodePermissions) {
|
||||
this.connectDialog.data.permissions.push({
|
||||
key: permission.key,
|
||||
name: permission.name,
|
||||
value: permission.value
|
||||
})
|
||||
value: permission.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
deleteBudget(index) {
|
||||
this.connectDialog.data.budgets.splice(index, 1)
|
||||
this.connectDialog.data.budgets.splice(index, 1);
|
||||
},
|
||||
addBudget() {
|
||||
this.connectDialog.data.budgets.push({
|
||||
budget_sats: 1000,
|
||||
used_budget_sats: 0,
|
||||
created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000,
|
||||
expiration: 'never'
|
||||
})
|
||||
expiration: "never",
|
||||
});
|
||||
},
|
||||
closeConnectDialog() {
|
||||
this.connectDialog.show = false
|
||||
this.loadConnectDialogData()
|
||||
this.connectDialog.show = false;
|
||||
this.loadConnectDialogData();
|
||||
},
|
||||
getWallet: function () {
|
||||
let wallet = undefined
|
||||
let wallet = undefined;
|
||||
for (let i = 0; i < this.g.user.wallets.length; i++) {
|
||||
if (this.g.user.wallets[i].id == this.selectedWallet) {
|
||||
wallet = this.g.user.wallets[i]
|
||||
break
|
||||
wallet = this.g.user.wallets[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return wallet
|
||||
return wallet;
|
||||
},
|
||||
async generateKeyPair() {
|
||||
while (!window.NobleSecp256k1) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1))
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
}
|
||||
const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey()
|
||||
const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes)
|
||||
const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey();
|
||||
const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes);
|
||||
const out = {
|
||||
privKeyBytes: privKeyBytes,
|
||||
pubKeyBytes: pubKeyBytes,
|
||||
privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes),
|
||||
pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1))
|
||||
}
|
||||
return out
|
||||
pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)),
|
||||
};
|
||||
return out;
|
||||
},
|
||||
deleteNWC: async function (pubkey) {
|
||||
Quasar.Dialog.create({
|
||||
title: 'Confirm Deletion',
|
||||
message: 'Are you sure you want to delete this connection?',
|
||||
title: "Confirm Deletion",
|
||||
message: "Are you sure you want to delete this connection?",
|
||||
cancel: true,
|
||||
persistent: true
|
||||
persistent: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
try {
|
||||
const wallet = this.getWallet()
|
||||
const wallet = this.getWallet();
|
||||
const response = await LNbits.api.request(
|
||||
'DELETE',
|
||||
"DELETE",
|
||||
`/nwcprovider/api/v1/nwc/${pubkey}`,
|
||||
wallet.adminkey
|
||||
)
|
||||
this.loadNwcs()
|
||||
wallet.adminkey,
|
||||
);
|
||||
this.loadNwcs();
|
||||
Quasar.Notify.create({
|
||||
type: 'positive',
|
||||
message: 'Deleted successfully'
|
||||
})
|
||||
type: "positive",
|
||||
message: "Deleted successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
LNbits.utils.notifyApiError(error);
|
||||
}
|
||||
})
|
||||
.onCancel(() => {
|
||||
// User canceled the operation
|
||||
})
|
||||
});
|
||||
},
|
||||
loadNwcs: async function () {
|
||||
const wallet = this.getWallet()
|
||||
const wallet = this.getWallet();
|
||||
if (!wallet) {
|
||||
this.nwcs = []
|
||||
return
|
||||
this.nwcs = [];
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const response = await LNbits.api.request(
|
||||
'GET',
|
||||
'/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true',
|
||||
wallet.adminkey
|
||||
)
|
||||
this.nwcs = response.data
|
||||
"GET",
|
||||
"/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true",
|
||||
wallet.adminkey,
|
||||
);
|
||||
this.nwcs = response.data;
|
||||
} catch (error) {
|
||||
this.nwcs = []
|
||||
this.nwcs = [];
|
||||
}
|
||||
try {
|
||||
const response = await LNbits.api.request(
|
||||
'GET',
|
||||
'/nwcprovider/api/v1/permissions',
|
||||
wallet.adminkey
|
||||
)
|
||||
const permissions = []
|
||||
"GET",
|
||||
"/nwcprovider/api/v1/permissions",
|
||||
wallet.adminkey,
|
||||
);
|
||||
const permissions = [];
|
||||
for (const [key, value] of Object.entries(response.data)) {
|
||||
permissions.push({
|
||||
key: key,
|
||||
name: value.name,
|
||||
value: value.default
|
||||
})
|
||||
value: value.default,
|
||||
});
|
||||
}
|
||||
this.nodePermissions = permissions
|
||||
this.nodePermissions = permissions;
|
||||
} catch (error) {
|
||||
Lnbits.utils.notifyApiError(error)
|
||||
Lnbits.utils.notifyApiError(error);
|
||||
}
|
||||
this.loadConnectDialogData()
|
||||
const newTableEntries = []
|
||||
this.loadConnectDialogData();
|
||||
const newTableEntries = [];
|
||||
for (const nwc of this.nwcs) {
|
||||
const t = Quasar.date.formatDate(
|
||||
new Date(nwc.data.created_at * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
"YYYY-MM-DD HH:mm",
|
||||
);
|
||||
const e =
|
||||
nwc.data.expires_at > 0
|
||||
? Quasar.date.formatDate(
|
||||
new Date(nwc.data.expires_at * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
"YYYY-MM-DD HH:mm",
|
||||
)
|
||||
: 'Never'
|
||||
: "Never";
|
||||
const l = Quasar.date.formatDate(
|
||||
new Date(nwc.data.last_used * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
"YYYY-MM-DD HH:mm",
|
||||
);
|
||||
const nwcTableEntry = {
|
||||
description: nwc.data.description,
|
||||
created_at: t,
|
||||
|
|
@ -256,130 +256,131 @@ window.app = Vue.createApp({
|
|||
pubkey: nwc.data.pubkey,
|
||||
permissions: nwc.data.permissions,
|
||||
budgets: [],
|
||||
status: 'Active'
|
||||
}
|
||||
status: "Active",
|
||||
};
|
||||
if (
|
||||
nwc.data.expires_at > 0 &&
|
||||
nwc.data.expires_at < new Date().getTime() / 1000
|
||||
) {
|
||||
nwcTableEntry.status = 'Expired'
|
||||
nwcTableEntry.status = "Expired";
|
||||
}
|
||||
for (const budget of nwc.budgets) {
|
||||
const createdAt = Quasar.date.formatDate(
|
||||
new Date(budget.created_at * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
let refreshWindow = budget.refresh_window
|
||||
"YYYY-MM-DD HH:mm",
|
||||
);
|
||||
let refreshWindow = budget.refresh_window;
|
||||
if (refreshWindow <= 0) {
|
||||
refreshWindow = 'Never'
|
||||
refreshWindow = "Never";
|
||||
} else if (refreshWindow == 60 * 60 * 24) {
|
||||
refreshWindow = 'Daily'
|
||||
refreshWindow = "Daily";
|
||||
} else if (refreshWindow == 60 * 60 * 24 * 7) {
|
||||
refreshWindow = 'Weekly'
|
||||
refreshWindow = "Weekly";
|
||||
} else if (refreshWindow == 60 * 60 * 24 * 30) {
|
||||
refreshWindow = 'Monthly'
|
||||
refreshWindow = "Monthly";
|
||||
} else if (refreshWindow == 60 * 60 * 24 * 365) {
|
||||
refreshWindow = 'Yearly'
|
||||
refreshWindow = "Yearly";
|
||||
}
|
||||
nwcTableEntry.budgets.push({
|
||||
budget_sats: budget.budget_msats / 1000,
|
||||
used_budget_sats: budget.used_budget_msats / 1000,
|
||||
created_at: createdAt,
|
||||
refresh_window: refreshWindow
|
||||
})
|
||||
refresh_window: refreshWindow,
|
||||
});
|
||||
}
|
||||
newTableEntries.push(nwcTableEntry)
|
||||
newTableEntries.push(nwcTableEntry);
|
||||
}
|
||||
this.nwcEntries = newTableEntries
|
||||
this.nwcEntries = newTableEntries;
|
||||
},
|
||||
closePairingDialog() {
|
||||
this.pairingDialog.show = false
|
||||
this.pairingDialog.show = false;
|
||||
},
|
||||
async showPairingDialog(secret) {
|
||||
let response = await LNbits.api.request(
|
||||
'GET',
|
||||
'/nwcprovider/api/v1/pairing/{SECRET}'
|
||||
)
|
||||
response = response.data
|
||||
response = response.replace('{SECRET}', secret)
|
||||
this.pairingDialog.data.pairingUrl = response
|
||||
this.pairingDialog.show = true
|
||||
"GET",
|
||||
"/nwcprovider/api/v1/pairing/{SECRET}",
|
||||
);
|
||||
response = response.data;
|
||||
response = response.replace("{SECRET}", secret);
|
||||
this.pairingDialog.data.pairingUrl = response;
|
||||
this.pairingDialog.show = true;
|
||||
},
|
||||
async confirmConnectDialog() {
|
||||
const keyPair = await this.generateKeyPair()
|
||||
const keyPair = await this.generateKeyPair();
|
||||
// timestamp
|
||||
let expires_at = 0
|
||||
let expires_at = 0;
|
||||
if (!this.connectDialog.data.neverExpires) {
|
||||
expires_at =
|
||||
new Date(this.connectDialog.data.expires_at).getTime() / 1000
|
||||
new Date(this.connectDialog.data.expires_at).getTime() / 1000;
|
||||
}
|
||||
const data = {
|
||||
permissions: [],
|
||||
description: this.connectDialog.data.description,
|
||||
expires_at: expires_at,
|
||||
budgets: []
|
||||
}
|
||||
budgets: [],
|
||||
};
|
||||
for (const permission of this.connectDialog.data.permissions) {
|
||||
if (permission.value) data.permissions.push(permission.key)
|
||||
if (permission.value) data.permissions.push(permission.key);
|
||||
}
|
||||
for (const budget of this.connectDialog.data.budgets) {
|
||||
const budget_msats = budget.budget_sats * 1000
|
||||
let refresh_window = 0
|
||||
const budget_msats = budget.budget_sats * 1000;
|
||||
let refresh_window = 0;
|
||||
switch (budget.expiry) {
|
||||
case 'Daily':
|
||||
refresh_window = 60 * 60 * 24
|
||||
break
|
||||
case 'Weekly':
|
||||
refresh_window = 60 * 60 * 24 * 7
|
||||
break
|
||||
case 'Monthly':
|
||||
refresh_window = 60 * 60 * 24 * 30
|
||||
break
|
||||
case 'Yearly':
|
||||
refresh_window = 60 * 60 * 24 * 365
|
||||
break
|
||||
case 'Never':
|
||||
refresh_window = 0
|
||||
break
|
||||
case "Daily":
|
||||
refresh_window = 60 * 60 * 24;
|
||||
break;
|
||||
case "Weekly":
|
||||
refresh_window = 60 * 60 * 24 * 7;
|
||||
break;
|
||||
case "Monthly":
|
||||
refresh_window = 60 * 60 * 24 * 30;
|
||||
break;
|
||||
case "Yearly":
|
||||
refresh_window = 60 * 60 * 24 * 365;
|
||||
break;
|
||||
case "Never":
|
||||
refresh_window = 0;
|
||||
break;
|
||||
}
|
||||
data.budgets.push({
|
||||
budget_msats: budget_msats,
|
||||
refresh_window: refresh_window,
|
||||
created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000
|
||||
})
|
||||
created_at:
|
||||
new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000,
|
||||
});
|
||||
}
|
||||
const wallet = this.getWallet()
|
||||
const wallet = this.getWallet();
|
||||
|
||||
try {
|
||||
const response = await LNbits.api.request(
|
||||
'PUT',
|
||||
'/nwcprovider/api/v1/nwc/' + keyPair.pubKey,
|
||||
"PUT",
|
||||
"/nwcprovider/api/v1/nwc/" + keyPair.pubKey,
|
||||
wallet.adminkey,
|
||||
data
|
||||
)
|
||||
this.closeConnectDialog()
|
||||
data,
|
||||
);
|
||||
this.closeConnectDialog();
|
||||
if (
|
||||
!response.data ||
|
||||
!response.data.data ||
|
||||
!response.data.data.pubkey
|
||||
) {
|
||||
LNbits.utils.notifyApiError('Error creating nwc pairing')
|
||||
return
|
||||
LNbits.utils.notifyApiError("Error creating nwc pairing");
|
||||
return;
|
||||
}
|
||||
this.showPairingDialog(keyPair.privKey)
|
||||
this.showPairingDialog(keyPair.privKey);
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
LNbits.utils.notifyApiError(error);
|
||||
}
|
||||
this.loadNwcs()
|
||||
}
|
||||
this.loadNwcs();
|
||||
},
|
||||
},
|
||||
|
||||
created: function () {
|
||||
this.loadNwcs()
|
||||
this.loadNwcs();
|
||||
},
|
||||
watch: {
|
||||
selectedWallet(newValue, oldValue) {
|
||||
this.loadNwcs()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.loadNwcs();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue