From b9552e1888a6ebfcc74a48b6886ede071da90990 Mon Sep 17 00:00:00 2001 From: David Clute Date: Thu, 23 Apr 2026 13:21:10 -0600 Subject: [PATCH 1/3] feat(ui): add warning before editing agent --- src/components/agents/DetailsModal.vue | 46 ++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/components/agents/DetailsModal.vue b/src/components/agents/DetailsModal.vue index 343e158..31eba70 100644 --- a/src/components/agents/DetailsModal.vue +++ b/src/components/agents/DetailsModal.vue @@ -1,5 +1,5 @@ @@ -66,27 +100,27 @@ function saveAgent() { tr th.has-text-right Contact td - .select.control + .select.control(:class="{ 'is-warning': isDirty('pending_contact') }") select(v-model="selectedAgent.pending_contact") option(v-for="contact in selectedAgent.available_contacts" :key="contact" :value="contact") {{ contact }} tr th.has-text-right Group td - input.input(type="text" v-model="selectedAgent.group" :class="{ 'is-danger': validation.group }") + input.input(type="text" v-model="selectedAgent.group" :class="{ 'is-danger': validation.group, 'is-warning': isDirty('group') }") p.help.has-text-danger(v-if="validation.group") {{ validation.group }} tr th.has-text-right Sleep Timer td .is-flex.is-align-items-center label.mr-3 min - input.input.mr-4(v-model="selectedAgent.sleep_min" type="number" placeholder="30" min="0" :max="selectedAgent.sleep_max" :class="{ 'is-danger': validation.beaconTimer }") + input.input.mr-4(v-model="selectedAgent.sleep_min" type="number" placeholder="30" min="0" :max="selectedAgent.sleep_max" :class="{ 'is-danger': validation.beaconTimer, 'is-warning': isDirty('sleep_min') }") label.mr-3 max - input.input(v-model="selectedAgent.sleep_max" type="number" placeholder="60" :min="selectedAgent.sleep_min" :class="{ 'is-danger': validation.beaconTimer }") + input.input(v-model="selectedAgent.sleep_max" type="number" placeholder="60" :min="selectedAgent.sleep_min" :class="{ 'is-danger': validation.beaconTimer, 'is-warning': isDirty('sleep_max') }") p.help.has-text-danger(v-if="validation.beaconTimer") {{ validation.beaconTimer }} tr th.has-text-right Watchdog Timer td - input.input(type="number" v-model="selectedAgent.watchdog" min="0" :class="{ 'is-danger': validation.watchdogTimer }") + input.input(type="number" v-model="selectedAgent.watchdog" min="0" :class="{ 'is-danger': validation.watchdogTimer, 'is-warning': isDirty('watchdog') }") p.help.has-text-danger(v-if="validation.watchdogTimer") {{ validation.watchdogTimer }} button.button.is-primary.is-fullwidth.mt-4(@click="saveAgent()") Save Settings hr From cf27f37a9b5b037f578e6b749c53919e5bb0a764 Mon Sep 17 00:00:00 2001 From: David Clute Date: Mon, 11 May 2026 09:38:51 -0600 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/components/agents/DetailsModal.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/agents/DetailsModal.vue b/src/components/agents/DetailsModal.vue index 31eba70..2a2f99b 100644 --- a/src/components/agents/DetailsModal.vue +++ b/src/components/agents/DetailsModal.vue @@ -32,6 +32,12 @@ watch(() => selectedAgent.value?.paw, (newPaw) => { } }, { immediate: true }); +watch(() => modals.value?.agents?.showDetails, (showDetails) => { + if (showDetails && selectedAgent.value) { + setOriginalAgent(); + } +}); + function isDirty(field) { if (!originalAgent.value || !selectedAgent.value) return false; return selectedAgent.value[field] !== originalAgent.value[field]; From bd4ba1a699f2ef6d102251915fad77a9bc73c027 Mon Sep 17 00:00:00 2001 From: David Clute Date: Mon, 11 May 2026 12:04:58 -0600 Subject: [PATCH 3/3] refactor(ui): auto-close agent modal on confirmed save VIRTS-4660 --- src/components/agents/DetailsModal.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/agents/DetailsModal.vue b/src/components/agents/DetailsModal.vue index 2a2f99b..11a44c2 100644 --- a/src/components/agents/DetailsModal.vue +++ b/src/components/agents/DetailsModal.vue @@ -40,7 +40,15 @@ watch(() => modals.value?.agents?.showDetails, (showDetails) => { function isDirty(field) { if (!originalAgent.value || !selectedAgent.value) return false; - return selectedAgent.value[field] !== originalAgent.value[field]; + + const numericFields = new Set(['sleep_min', 'sleep_max', 'watchdog']); + const currentValue = selectedAgent.value[field]; + const originalValue = originalAgent.value[field]; + if (numericFields.has(field)) { + return Number(currentValue) !== Number(originalValue); + } + + return currentValue !== originalValue; } const hasAnyChanges = computed(() => { @@ -87,6 +95,10 @@ function saveAgent() { agentStore.saveSelectedAgent($api); // Reset the baseline after a successful save so the yellow boxes go back to normal setOriginalAgent(); + // Close the modal after saving + if (modals.value) { + modals.value.agents.showDetails = false; + } } }