diff --git a/webclient-vue/src/app/App.vue b/webclient-vue/src/app/App.vue
index 798c710..f16c21a 100644
--- a/webclient-vue/src/app/App.vue
+++ b/webclient-vue/src/app/App.vue
@@ -1,13 +1,16 @@
-
-
-
+
+
+
+
+
diff --git a/webclient-vue/src/composables/useAreaAssign.js b/webclient-vue/src/composables/useAreaAssign.js
index 532295f..986f4ae 100644
--- a/webclient-vue/src/composables/useAreaAssign.js
+++ b/webclient-vue/src/composables/useAreaAssign.js
@@ -34,10 +34,11 @@
if (!result.ok) {
assignError.value = result.error?.message || "Failed to assign area";
- return;
+ return result;
}
showAssignModal.value = false;
+ return result;
}
return {
diff --git a/webclient-vue/src/features/areas/pages/AreaDetailPage.vue b/webclient-vue/src/features/areas/pages/AreaDetailPage.vue
index 6da2843..ba92f82 100644
--- a/webclient-vue/src/features/areas/pages/AreaDetailPage.vue
+++ b/webclient-vue/src/features/areas/pages/AreaDetailPage.vue
@@ -154,6 +154,7 @@
GnInput,
GnAlert,
GnSelect,
+ useToast,
} from "gnexus-ui-kit/vue";
import AppLoadingState from "../../../components/feedback/AppLoadingState.vue";
import AppErrorState from "../../../components/feedback/AppErrorState.vue";
@@ -168,6 +169,7 @@
const router = useRouter();
const areasStore = useAreasStore();
const favoritesStore = useFavoritesStore();
+const toast = useToast();
const {
showAssignModal,
@@ -257,6 +259,7 @@
}
showRenameModal.value = false;
+ toast.success({ title: "Renamed", text: "Area renamed successfully" });
}
function openRemove() {
@@ -280,6 +283,7 @@
}
showRemoveDialog.value = false;
+ toast.success({ title: "Removed", text: "Area removed successfully" });
router.push({ name: "areas-tree" });
}
@@ -289,7 +293,10 @@
async function submitAssign() {
const id = area.value?.id;
- await submitAssignCore(id, (itemId, parentId) => areasStore.assignToArea(itemId, parentId));
+ const result = await submitAssignCore(id, (itemId, parentId) => areasStore.assignToArea(itemId, parentId));
+ if (result?.ok) {
+ toast.success({ title: "Assigned", text: "Area assigned successfully" });
+ }
}
async function unassign() {
diff --git a/webclient-vue/src/features/areas/pages/AreaTreePage.vue b/webclient-vue/src/features/areas/pages/AreaTreePage.vue
index 76b0545..d112571 100644
--- a/webclient-vue/src/features/areas/pages/AreaTreePage.vue
+++ b/webclient-vue/src/features/areas/pages/AreaTreePage.vue
@@ -59,6 +59,7 @@
GnModal,
GnInput,
GnAlert,
+ useToast,
} from "gnexus-ui-kit/vue";
import AreaTreeNode from "../components/AreaTreeNode.vue";
import AppLoadingState from "../../../components/feedback/AppLoadingState.vue";
@@ -66,6 +67,7 @@
import AppEmptyState from "../../../components/feedback/AppEmptyState.vue";
const areasStore = useAreasStore();
+const toast = useToast();
const showCreateModal = ref(false);
const createLoading = ref(false);
@@ -93,6 +95,7 @@
}
showCreateModal.value = false;
+ toast.success({ title: "Created", text: "Area created successfully" });
}
onMounted(() => {
diff --git a/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue b/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue
index 6d11878..e6e935e 100644
--- a/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue
+++ b/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue
@@ -60,10 +60,6 @@
@assign="openAssign"
/>
-
- {{ rebootError }}
-
-
Description
{{ device.description }}
@@ -185,6 +181,7 @@
GnAlert,
GnTable,
GnSelect,
+ useToast,
} from "gnexus-ui-kit/vue";
import AppEmptyState from "../../../components/feedback/AppEmptyState.vue";
import AppErrorState from "../../../components/feedback/AppErrorState.vue";
@@ -197,6 +194,7 @@
const router = useRouter();
const devicesStore = useDevicesStore();
const areasStore = useAreasStore();
+const toast = useToast();
const {
areaOptions,
@@ -232,7 +230,6 @@
const removeDialogMessage = ref("");
const removeLoading = ref(false);
const removeError = ref("");
-const rebootError = ref("");
const channelColumns = [
{ key: "channel", label: "Channel" },
@@ -285,6 +282,7 @@
}
showEditModal.value = false;
+ toast.success({ title: "Updated", text: "Device updated successfully" });
}
function openAssign() {
@@ -292,7 +290,10 @@
}
async function submitAssign() {
- await submitAssignCore(deviceId.value, devicesStore.assignToArea.bind(devicesStore));
+ const result = await submitAssignCore(deviceId.value, devicesStore.assignToArea.bind(devicesStore));
+ if (result?.ok) {
+ toast.success({ title: "Assigned", text: "Device assigned to area successfully" });
+ }
}
async function unassign() {
@@ -321,17 +322,19 @@
}
showRemoveDialog.value = false;
+ toast.success({ title: "Removed", text: "Device removed successfully" });
router.push({ name: "devices" });
}
async function reboot() {
if (!device.value) return;
- rebootError.value = "";
const result = await devicesStore.rebootDevice(device.value.id);
if (!result.ok) {
- rebootError.value = result.error?.message || "Failed to reboot device";
+ toast.error({ title: "Reboot failed", text: result.error?.message || "Failed to reboot device" });
+ } else {
+ toast.success({ title: "Rebooting", text: `Device ${device.value.name || device.value.alias} is rebooting` });
}
}
diff --git a/webclient-vue/src/features/devices/pages/DevicesScanningPage.vue b/webclient-vue/src/features/devices/pages/DevicesScanningPage.vue
index 9435fb4..1610070 100644
--- a/webclient-vue/src/features/devices/pages/DevicesScanningPage.vue
+++ b/webclient-vue/src/features/devices/pages/DevicesScanningPage.vue
@@ -129,12 +129,14 @@
GnModal,
GnInput,
GnAlert,
+ useToast,
} from "gnexus-ui-kit/vue";
import AppEmptyState from "../../../components/feedback/AppEmptyState.vue";
import AppErrorState from "../../../components/feedback/AppErrorState.vue";
import AppLoadingState from "../../../components/feedback/AppLoadingState.vue";
const scanningStore = useScanningStore();
+const toast = useToast();
const showSetupModal = ref(false);
const setupLoading = ref(false);
@@ -193,6 +195,7 @@
}
showSetupModal.value = false;
+ toast.success({ title: "Device added", text: `Device ${setupForm.alias || setupForm.name || ""} added successfully` });
}
diff --git a/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue b/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue
index 9dbc287..8105059 100644
--- a/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue
+++ b/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue
@@ -115,10 +115,6 @@
/>
-
- {{ resultAlert.title }}
- {{ resultAlert.message }}
-
{
- const r = scriptsStore.lastRunResult;
- if (!r) return null;
-
- if (r.ok) {
- return {
- variant: "success",
- title: `Ran ${r.alias}`,
- message: r.execTime ? `Exec time: ${r.execTime}` : undefined,
- };
- }
-
- return {
- variant: "danger",
- title: `Failed ${r.alias}`,
- message: r.error?.message || "Unknown error",
- };
-});
-
async function run() {
if (!script.value?.alias) return;
- resultAlert.value = null;
const result = await scriptsStore.runScript(script.value.alias);
- resultAlert.value = resultAlertComputed.value;
+ if (result?.ok) {
+ toast.success({ title: `Ran ${script.value.alias}`, text: result.execTime ? `Exec time: ${result.execTime}` : undefined });
+ } else {
+ toast.error({ title: `Failed ${script.value.alias}`, text: result?.error?.message || "Unknown error" });
+ }
}
async function toggleState(enabled) {
@@ -343,17 +323,11 @@
result = await scriptsStore.setScopeState(id, enabled);
}
+ const alias = script.value?.alias || id;
if (result && !result.ok) {
- resultAlert.value = {
- variant: "danger",
- title: `Failed to ${enabled ? "enable" : "disable"} ${script.value?.alias || id}`,
- message: result.error?.message || "Unknown error",
- };
+ toast.error({ title: `Failed to ${enabled ? "enable" : "disable"} ${alias}`, text: result.error?.message || "Unknown error" });
} else if (result) {
- resultAlert.value = {
- variant: "success",
- title: `${enabled ? "Enabled" : "Disabled"} ${script.value?.alias || id}`,
- };
+ toast.success({ title: `${enabled ? "Enabled" : "Disabled"} ${alias}` });
}
}
@@ -363,7 +337,10 @@
async function submitAssign() {
const id = script.value?.id;
- await submitAssignCore(id, scriptsStore.assignToArea.bind(scriptsStore));
+ const result = await submitAssignCore(id, scriptsStore.assignToArea.bind(scriptsStore));
+ if (result?.ok) {
+ toast.success({ title: "Assigned", text: "Script assigned to area successfully" });
+ }
}
async function loadCode() {
diff --git a/webclient-vue/src/features/scripts/pages/ScriptsActionsPage.vue b/webclient-vue/src/features/scripts/pages/ScriptsActionsPage.vue
index 40e97af..b8e3043 100644
--- a/webclient-vue/src/features/scripts/pages/ScriptsActionsPage.vue
+++ b/webclient-vue/src/features/scripts/pages/ScriptsActionsPage.vue
@@ -51,16 +51,11 @@
-
-
- {{ resultAlert.title }}
- {{ resultAlert.message }}
-