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 }}

-