diff --git a/webclient-vue/src/components/layout/PageActionsDropdown.vue b/webclient-vue/src/components/layout/PageActionsDropdown.vue new file mode 100644 index 0000000..e147d71 --- /dev/null +++ b/webclient-vue/src/components/layout/PageActionsDropdown.vue @@ -0,0 +1,17 @@ + + + diff --git a/webclient-vue/src/features/areas/pages/AreaDetailPage.vue b/webclient-vue/src/features/areas/pages/AreaDetailPage.vue index ea28edf..a585e5f 100644 --- a/webclient-vue/src/features/areas/pages/AreaDetailPage.vue +++ b/webclient-vue/src/features/areas/pages/AreaDetailPage.vue @@ -19,22 +19,7 @@
@@ -172,6 +157,7 @@ import AreaAssignSection from "../../../components/area/AreaAssignSection.vue"; import DeviceTable from "../../../components/device/DeviceTable.vue"; import ScriptTable from "../../../components/script/ScriptTable.vue"; +import PageActionsDropdown from "../../../components/layout/PageActionsDropdown.vue"; const route = useRoute(); const router = useRouter(); @@ -189,6 +175,22 @@ const area = computed(() => areasStore.areasById[String(route.params.id)] || null); const isFavorite = computed(() => (area.value ? favoritesStore.has(area.value.id) : false)); + +const areaActions = computed(() => [ + { label: "Rename", icon: "ph-pencil", onSelect: openRename }, + { + label: area.value?.parent_id > 0 ? "Change parent area" : "Assign to area", + icon: "ph-map-pin", + onSelect: openAssign, + }, + { + label: isFavorite.value ? "Unstar" : "Star", + icon: "ph-star", + onSelect: () => favoritesStore.toggle(area.value?.id), + }, + { label: "Remove", icon: "ph-trash", danger: true, onSelect: openRemove }, +]); + const parentArea = computed(() => { if (!area.value || area.value.parent_id <= 0) return null; return areasStore.areasById[String(area.value.parent_id)] || null; diff --git a/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue b/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue index 133fc33..2d97298 100644 --- a/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue +++ b/webclient-vue/src/features/devices/pages/DeviceDetailPage.vue @@ -12,23 +12,7 @@
@@ -198,6 +182,7 @@ import AppLoadingState from "../../../components/feedback/AppLoadingState.vue"; import AreaBadgeLink from "../../../components/area/AreaBadgeLink.vue"; import AreaAssignSection from "../../../components/area/AreaAssignSection.vue"; +import PageActionsDropdown from "../../../components/layout/PageActionsDropdown.vue"; const route = useRoute(); const router = useRouter(); @@ -243,6 +228,22 @@ { key: "type", label: "Type" }, ]; +const deviceActions = computed(() => [ + { label: "Edit", icon: "ph-pencil", onSelect: openEdit }, + { + label: device.value?.area_id ? "Change area" : "Assign to area", + icon: "ph-map-pin", + onSelect: openAssign, + }, + { + label: "Reboot", + icon: "ph-arrow-clockwise", + disabled: devicesStore.isRebooting(device.value?.id), + onSelect: reboot, + }, + { label: "Remove", icon: "ph-trash", danger: true, onSelect: remove }, +]); + function openEdit() { if (!device.value) return; editForm.name = device.value.name || ""; diff --git a/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue b/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue index 566bc3b..c6f994f 100644 --- a/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue +++ b/webclient-vue/src/features/scripts/pages/ScriptDetailPage.vue @@ -17,24 +17,7 @@ label="Enabled" @update:model-value="toggleState($event)" /> - - {{ script.area_id ? 'Change area' : 'Assign to area' }} - - - Run - + @@ -197,6 +180,7 @@ import AppEmptyState from "../../../components/feedback/AppEmptyState.vue"; import AreaBadgeLink from "../../../components/area/AreaBadgeLink.vue"; import AreaAssignSection from "../../../components/area/AreaAssignSection.vue"; +import PageActionsDropdown from "../../../components/layout/PageActionsDropdown.vue"; const route = useRoute(); const scriptsStore = useScriptsStore(); @@ -219,6 +203,26 @@ const isRegular = computed(() => scriptType.value === "regular"); const isScope = computed(() => scriptType.value === "scopes"); +const scriptActions = computed(() => { + const actions = []; + if (!isScope.value) { + actions.push({ + label: script.value?.area_id ? "Change area" : "Assign to area", + icon: "ph-map-pin", + onSelect: openAssign, + }); + } + if (isAction.value) { + actions.push({ + label: "Run", + icon: "ph-play", + disabled: script.value?.state !== "enabled" || scriptsStore.isRunning(script.value?.alias), + onSelect: run, + }); + } + return actions; +}); + const kicker = computed(() => { if (isAction.value) return "Actions"; if (isRegular.value) return "Regular";