feat(TutorialModal, AddInterfacePage, InterfacesPage): enhance UI components and integrate global state management for interface changes
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
max-width="800"
|
||||
transition="dialog-bottom-transition"
|
||||
class="tutorial-dialog"
|
||||
persistent
|
||||
@update:model-value="onVisibleUpdate"
|
||||
>
|
||||
<v-card class="flex flex-col h-full bg-white dark:bg-zinc-950 border-0 overflow-hidden">
|
||||
@@ -42,7 +43,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 w-full mt-8">
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-shield-lock" color="blue" size="32"></v-icon>
|
||||
<div>
|
||||
@@ -53,20 +54,20 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-map-marker-path" color="purple" size="32"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Enhanced Maps</div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Maps</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
OpenLayers w/ MBTiles support and custom API endpoints.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-phone-voip" color="green" size="32"></v-icon>
|
||||
<v-icon icon="mdi-phone" color="green" size="32"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Full LXST Voice</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
@@ -75,29 +76,42 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-tools" color="orange" size="32"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Advanced Tools</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
Micron, Paper Messages, RNS tools, Crawler & Archiver.
|
||||
Micron Editor, Paper Messages, RNS tools, Docs.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-database-search" color="teal" size="32"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Crawler & Archiver</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
Automated network crawling and page archiving.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-keyboard-outline" color="red" size="32"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">Command Palette</div>
|
||||
<div class="font-bold text-gray-900 dark:text-white">
|
||||
Command Palette + Keybindings
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
Navigate everything instantly with a few keystrokes.
|
||||
Navigate everything instantly and customize shortcuts.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800"
|
||||
class="flex items-start gap-4 p-4 rounded-2xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-translate" color="cyan" size="32"></v-icon>
|
||||
<div>
|
||||
@@ -524,7 +538,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 w-full mt-12">
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-shield-lock" color="blue" size="40"></v-icon>
|
||||
<div>
|
||||
@@ -538,11 +552,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-map-marker-path" color="purple" size="40"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">Enhanced Maps</div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">Maps</div>
|
||||
<div class="text-gray-500">
|
||||
OpenLayers support with offline MBTiles and custom API endpoints for online
|
||||
maps.
|
||||
@@ -550,9 +564,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-phone-voip" color="green" size="40"></v-icon>
|
||||
<v-icon icon="mdi-phone" color="green" size="40"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">Full LXST Voice</div>
|
||||
<div class="text-gray-500">
|
||||
@@ -562,30 +576,45 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-tools" color="orange" size="40"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">Advanced Tools</div>
|
||||
<div class="text-gray-500">
|
||||
Micron editor, paper messages, RNS tools, network Crawler and Archiver.
|
||||
Micron editor, paper messages, RNS tools, and integrated documentation.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-database-search" color="teal" size="40"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">
|
||||
Crawler & Archiver
|
||||
</div>
|
||||
<div class="text-gray-500">
|
||||
Automated network crawling and page archiving tools for offline browsing.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-keyboard-outline" color="red" size="40"></v-icon>
|
||||
<div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">Command Palette</div>
|
||||
<div class="font-bold text-xl text-gray-900 dark:text-white">
|
||||
Command Palette + Keybindings
|
||||
</div>
|
||||
<div class="text-gray-500">
|
||||
Navigate the entire application and access tools instantly with a single
|
||||
shortcut.
|
||||
Navigate the entire application and customize your workflow with instant
|
||||
shortcuts.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-transform hover:scale-[1.02]"
|
||||
class="flex items-start gap-6 p-6 rounded-3xl bg-gray-50 dark:bg-zinc-900 text-left border border-gray-100 dark:border-zinc-800 transition-all hover:scale-[1.03] hover:shadow-2xl hover:z-10"
|
||||
>
|
||||
<v-icon icon="mdi-translate" color="cyan" size="40"></v-icon>
|
||||
<div>
|
||||
@@ -710,6 +739,11 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
:menu-props="{ attach: true }"
|
||||
></v-select>
|
||||
|
||||
<v-text-field
|
||||
@@ -720,6 +754,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
|
||||
<!-- TCP Client Fields -->
|
||||
@@ -733,6 +771,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="newInterface.target_port"
|
||||
@@ -742,6 +784,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
@@ -761,6 +807,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="newInterface.listen_port"
|
||||
@@ -770,6 +820,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
@@ -796,6 +850,11 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
:menu-props="{ attach: true }"
|
||||
>
|
||||
<template #item="{ props, item }">
|
||||
<v-list-item v-bind="props" :subtitle="item.raw.product"></v-list-item>
|
||||
@@ -814,6 +873,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
</template>
|
||||
|
||||
@@ -827,6 +890,10 @@
|
||||
density="comfortable"
|
||||
rounded="xl"
|
||||
class="bg-white dark:bg-zinc-800"
|
||||
bg-color="white"
|
||||
base-color="gray"
|
||||
color="blue"
|
||||
persistent-placeholder
|
||||
></v-text-field>
|
||||
</template>
|
||||
|
||||
@@ -1006,6 +1073,7 @@ import logoUrl from "../assets/images/logo.png";
|
||||
import ToastUtils from "../js/ToastUtils";
|
||||
import DialogUtils from "../js/DialogUtils";
|
||||
import ElectronUtils from "../js/ElectronUtils";
|
||||
import GlobalState from "../js/GlobalState";
|
||||
|
||||
export default {
|
||||
name: "TutorialModal",
|
||||
@@ -1095,6 +1163,11 @@ export default {
|
||||
enabled: true,
|
||||
});
|
||||
ToastUtils.success(`Added interface: ${iface.name}`);
|
||||
|
||||
// track change
|
||||
GlobalState.hasPendingInterfaceChanges = true;
|
||||
GlobalState.modifiedInterfaceNames.add(iface.name);
|
||||
|
||||
this.nextStep();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -1149,6 +1222,11 @@ export default {
|
||||
|
||||
await window.axios.post("/api/v1/reticulum/interfaces/add", payload);
|
||||
ToastUtils.success(`Added interface: ${this.newInterface.name}`);
|
||||
|
||||
// track change
|
||||
GlobalState.hasPendingInterfaceChanges = true;
|
||||
GlobalState.modifiedInterfaceNames.add(this.newInterface.name);
|
||||
|
||||
this.nextStep();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -1197,6 +1275,60 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tutorial-dialog :deep(.v-field) {
|
||||
border-radius: 1rem !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-field--variant-outlined .v-field__outline) {
|
||||
--v-field-border-opacity: 0.15;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-field--focused .v-field__outline) {
|
||||
--v-field-border-opacity: 1;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-field__input) {
|
||||
padding-top: 24px !important;
|
||||
padding-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-label.v-field-label--floating) {
|
||||
transform: translateY(-8px) scale(0.75) !important;
|
||||
font-weight: 800 !important;
|
||||
text-transform: uppercase !important;
|
||||
letter-spacing: 0.05em !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-select .v-theme--light),
|
||||
.tutorial-dialog :deep(.v-list),
|
||||
.tutorial-dialog :deep(.v-list-item) {
|
||||
background-color: white !important;
|
||||
color: #111827 !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-list-item-title),
|
||||
.tutorial-dialog :deep(.v-list-item-subtitle) {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.dark .v-list),
|
||||
.tutorial-dialog :deep(.dark .v-list-item) {
|
||||
background-color: #18181b !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-field__input) {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.v-label.v-field-label) {
|
||||
color: #6b7280 !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog :deep(.dark .v-label.v-field-label) {
|
||||
color: #a1a1aa !important;
|
||||
}
|
||||
|
||||
.tutorial-dialog .v-overlay__content {
|
||||
border-radius: 2rem !important;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1069,6 +1069,7 @@ import ExpandingSection from "./ExpandingSection.vue";
|
||||
import FormLabel from "../forms/FormLabel.vue";
|
||||
import FormSubLabel from "../forms/FormSubLabel.vue";
|
||||
import Toggle from "../forms/Toggle.vue";
|
||||
import GlobalState from "../../js/GlobalState";
|
||||
|
||||
export default {
|
||||
name: "AddInterfacePage",
|
||||
@@ -1474,12 +1475,13 @@ export default {
|
||||
DialogUtils.alert(response.data.message);
|
||||
}
|
||||
|
||||
// track change
|
||||
GlobalState.hasPendingInterfaceChanges = true;
|
||||
GlobalState.modifiedInterfaceNames.add(this.newInterfaceName);
|
||||
|
||||
// go to interfaces page
|
||||
this.$router.push({
|
||||
name: "interfaces",
|
||||
query: {
|
||||
restart_required: this.newInterfaceName,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
const message = e.response?.data?.message ?? "failed to add interface";
|
||||
|
||||
@@ -144,6 +144,7 @@ import ImportInterfacesModal from "./ImportInterfacesModal.vue";
|
||||
import DownloadUtils from "../../js/DownloadUtils";
|
||||
import MaterialDesignIcon from "../MaterialDesignIcon.vue";
|
||||
import ToastUtils from "../../js/ToastUtils";
|
||||
import GlobalState from "../../js/GlobalState";
|
||||
|
||||
export default {
|
||||
name: "InterfacesPage",
|
||||
@@ -160,13 +161,17 @@ export default {
|
||||
searchTerm: "",
|
||||
statusFilter: "all",
|
||||
typeFilter: "all",
|
||||
hasPendingInterfaceChanges: false,
|
||||
reloadingRns: false,
|
||||
modifiedInterfaceNames: new Set(),
|
||||
isReticulumRunning: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasPendingInterfaceChanges() {
|
||||
return GlobalState.hasPendingInterfaceChanges;
|
||||
},
|
||||
modifiedInterfaceNames() {
|
||||
return GlobalState.modifiedInterfaceNames;
|
||||
},
|
||||
isElectron() {
|
||||
return ElectronUtils.isElectron();
|
||||
},
|
||||
@@ -237,11 +242,6 @@ export default {
|
||||
this.loadInterfaces();
|
||||
this.updateInterfaceStats();
|
||||
|
||||
// check if we have a restart required from adding an interface
|
||||
if (this.$route.query.restart_required) {
|
||||
this.trackInterfaceChange(this.$route.query.restart_required);
|
||||
}
|
||||
|
||||
// update info every few seconds
|
||||
this.reloadInterval = setInterval(() => {
|
||||
this.updateInterfaceStats();
|
||||
@@ -252,9 +252,9 @@ export default {
|
||||
ElectronUtils.relaunch();
|
||||
},
|
||||
trackInterfaceChange(interfaceName = null) {
|
||||
this.hasPendingInterfaceChanges = true;
|
||||
GlobalState.hasPendingInterfaceChanges = true;
|
||||
if (interfaceName) {
|
||||
this.modifiedInterfaceNames.add(interfaceName);
|
||||
GlobalState.modifiedInterfaceNames.add(interfaceName);
|
||||
}
|
||||
},
|
||||
isInterfaceEnabled: function (iface) {
|
||||
@@ -350,7 +350,6 @@ export default {
|
||||
try {
|
||||
// fetch exported interfaces
|
||||
const response = await window.axios.post("/api/v1/reticulum/interfaces/export");
|
||||
this.trackInterfaceChange();
|
||||
|
||||
// download file to browser
|
||||
DownloadUtils.downloadFile("meshchat_interfaces.txt", new Blob([response.data]));
|
||||
@@ -365,7 +364,6 @@ export default {
|
||||
const response = await window.axios.post("/api/v1/reticulum/interfaces/export", {
|
||||
selected_interface_names: [interfaceName],
|
||||
});
|
||||
this.trackInterfaceChange();
|
||||
|
||||
// download file to browser
|
||||
DownloadUtils.downloadFile(`${interfaceName}.txt`, new Blob([response.data]));
|
||||
@@ -397,8 +395,8 @@ export default {
|
||||
this.reloadingRns = true;
|
||||
const response = await window.axios.post("/api/v1/reticulum/reload");
|
||||
ToastUtils.success(response.data.message);
|
||||
this.hasPendingInterfaceChanges = false;
|
||||
this.modifiedInterfaceNames.clear();
|
||||
GlobalState.hasPendingInterfaceChanges = false;
|
||||
GlobalState.modifiedInterfaceNames.clear();
|
||||
await this.loadInterfaces();
|
||||
} catch (e) {
|
||||
ToastUtils.error(e.response?.data?.error || "Failed to reload Reticulum!");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { mount } from "@vue/test-utils";
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import InterfacesPage from "../../meshchatx/src/frontend/components/interfaces/InterfacesPage.vue";
|
||||
import GlobalState from "../../meshchatx/src/frontend/js/GlobalState";
|
||||
|
||||
// Mock global objects
|
||||
const mockAxios = {
|
||||
@@ -36,6 +37,8 @@ describe("InterfacesPage.vue", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mockAxios.get.mockResolvedValue({ data: { interfaces: [], app_info: { is_reticulum_running: true } } });
|
||||
GlobalState.hasPendingInterfaceChanges = false;
|
||||
GlobalState.modifiedInterfaceNames.clear();
|
||||
});
|
||||
|
||||
it("loads interfaces on mount", async () => {
|
||||
@@ -98,8 +101,8 @@ describe("InterfacesPage.vue", () => {
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.vm.hasPendingInterfaceChanges = true;
|
||||
wrapper.vm.modifiedInterfaceNames.add("test-iface");
|
||||
GlobalState.hasPendingInterfaceChanges = true;
|
||||
GlobalState.modifiedInterfaceNames.add("test-iface");
|
||||
|
||||
await wrapper.vm.reloadRns();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user