allow editing existing interfaces and don't overwrite unknown config values that may already exist

This commit is contained in:
liamcottle 2024-05-30 01:16:46 +12:00
commit 36c22c508b
2 changed files with 100 additions and 27 deletions

View file

@ -699,7 +699,7 @@
<div class="ml-2">Reticulum WebChat must be restarted for any interface changes to take effect.</div>
</div>
<button @click="tab = 'interfaces.add'" type="button" class="my-auto inline-flex items-center gap-x-1 rounded-md bg-gray-500 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
<button @click="showAddInterfaceForm" type="button" class="my-auto inline-flex items-center gap-x-1 rounded-md bg-gray-500 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
@ -771,7 +771,7 @@
</div>
<!-- enable/disable interface button -->
<div class="my-auto mr-2">
<div class="my-auto mr-1">
<button v-if="isInterfaceEnabled(iface)" @click="disableInterface(interface_name)" type="button" class="cursor-pointer">
<span class="flex text-gray-700 bg-gray-100 hover:bg-gray-200 p-2 rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
@ -788,6 +788,17 @@
</button>
</div>
<!-- edit interface button -->
<div class="my-auto mr-1">
<button @click="editInterface(interface_name)" type="button" class="cursor-pointer">
<span class="flex text-gray-700 bg-gray-100 hover:bg-gray-200 p-2 rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
</svg>
</span>
</button>
</div>
<!-- delete interface button -->
<div class="my-auto mr-2">
<button @click="deleteInterface(interface_name)" type="button" class="cursor-pointer">
@ -822,7 +833,10 @@
<!-- add interface form -->
<div class="bg-white rounded shadow divide-y divide-gray-200">
<div class="p-2 font-bold">Add Interface</div>
<div class="p-2 font-bold">
<span v-if="isEditingInterface">Edit Interface</span>
<span v-else>Add Interface</span>
</div>
<div class="p-2 space-y-3">
<!-- interface name -->
@ -898,7 +912,8 @@
<!-- add button -->
<button @click="addInterface" type="button" class="bg-green-500 hover:bg-green-400 focus-visible:outline-green-500 my-auto inline-flex items-center gap-x-1 rounded-md p-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2">
Add Interface
<span v-if="isEditingInterface">Save Interface</span>
<span v-else>Add Interface</span>
</button>
</div>
@ -936,7 +951,7 @@
audioCalls: [],
lxmfDeliveryAnnounces: [],
tab: "messages",
tab: "interfaces",
peers: {},
peersSearchTerm: "",
selectedPeer: null,
@ -2109,6 +2124,65 @@
// reload interfaces
await this.loadInterfaces();
},
showAddInterfaceForm() {
this.resetAddInterfaceForm();
this.loadComports();
this.isEditingInterface = false;
this.tab = "interfaces.add";
},
showEditInterfaceForm() {
this.resetAddInterfaceForm();
this.loadComports();
this.isEditingInterface = true;
this.tab = "interfaces.add";
},
resetAddInterfaceForm() {
// clear add interface form
this.newInterfaceName = null;
this.newInterfaceType = null;
// tcp client interface
this.newInterfaceTargetHost = null;
this.newInterfaceTargetPort = null;
// rnode interface
this.newInterfacePort = null;
this.newInterfaceFrequency = null;
this.newInterfaceBandwidth = null;
this.newInterfaceTxpower = null;
this.newInterfaceSpreadingFactor = null;
this.newInterfaceCodingRate = null;
},
async editInterface(interfaceName) {
// find interface
const iface = this.interfaces[interfaceName];
if(!iface){
return;
}
// go to edit interface tab
this.showEditInterfaceForm();
// set form values
this.newInterfaceName = interfaceName;
this.newInterfaceType = iface.type;
// tcp client interface
this.newInterfaceTargetHost = iface.target_host;
this.newInterfaceTargetPort = iface.target_port;
// rnode interface
this.newInterfacePort = iface.port;
this.newInterfaceFrequency = iface.frequency;
this.newInterfaceBandwidth = iface.bandwidth;
this.newInterfaceTxpower = iface.txpower;
this.newInterfaceSpreadingFactor = iface.spreadingfactor;
this.newInterfaceCodingRate = iface.codingrate;
},
async deleteInterface(interfaceName) {
@ -2137,6 +2211,7 @@
// add interface
const response = await window.axios.post(`/api/v1/reticulum/interfaces/add`, {
allow_overwriting_interface: this.isEditingInterface,
// required values
name: this.newInterfaceName,
type: this.newInterfaceType,
@ -2152,19 +2227,8 @@
codingrate: this.newInterfaceCodingRate,
});
// clear add interface form
this.newInterfaceName = null;
this.newInterfaceType = null;
// tcp client interface
this.newInterfaceTargetHost = null;
this.newInterfaceTargetPort = null;
// rnode interface
this.newInterfacePort = null;
this.newInterfaceFrequency = null;
this.newInterfaceBandwidth = null;
this.newInterfaceTxpower = null;
this.newInterfaceSpreadingFactor = null;
this.newInterfaceCodingRate = null;
// reset add interface form
this.resetAddInterfaceForm();
// go to interfaces tab
this.tab = "interfaces";

27
web.py
View file

@ -239,6 +239,7 @@ class ReticulumWebChat:
data = await request.json()
interface_name = data.get('name')
interface_type = data.get('type')
allow_overwriting_interface = data.get('allow_overwriting_interface', False)
# ensure name is provided
if interface_name is None or interface_name == "":
@ -258,16 +259,18 @@ class ReticulumWebChat:
interfaces = self.reticulum.config["interfaces"]
# ensure name is not for an existing interface, to prevent overwriting
if interface_name in interfaces:
if allow_overwriting_interface is False and interface_name in interfaces:
return web.json_response({
"message": "Name is already in use by another interface",
}, status=422)
# create interface details
interface_details = {
"type": interface_type,
"interface_enabled": str(data.get('enabled', False)),
}
# get existing interface details if available
interface_details = {}
if interface_name in interfaces:
interface_details = interfaces[interface_name]
# update interface details
interface_details["type"] = interface_type
# handle tcp client interface
if interface_type == "TCPClientInterface":
@ -350,9 +353,15 @@ class ReticulumWebChat:
# save config
self.reticulum.config.write()
return web.json_response({
"message": "Interface has been added",
})
if allow_overwriting_interface:
return web.json_response({
"message": "Interface has been saved",
})
else:
return web.json_response({
"message": "Interface has been added",
})
# handle websocket clients
@routes.get("/ws")