feat(config): pending-changes engine — desired vs actual VM config with apply/revert#73
Conversation
… and change category mapping
… fix setTags endpoint path
Implements diff engine that compares desiredConfig vs actualConfig on deployed VM nodes, categorising changes as live/restart/redeploy and providing revertField, revertAll, and updateDesired mutation helpers.
…dConfig from overwrites
…rt icons and pending actions
# Conflicts: # src/components/ConfigPanel.vue # vite.config.js
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d4e3e80238
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { getChangeCategory, getChangeLabel } from '@/constants/changeCategories' | ||
| import type { PendingChange } from '@/services/proxmox/types' | ||
|
|
||
| const DIFFABLE_FIELDS = ['name', 'cores', 'memory', 'tags'] |
There was a problem hiding this comment.
Diff description fields in pending-change engine
The pending-change diff only checks ['name', 'cores', 'memory', 'tags'], even though the deployed VM form now allows editing description and ApplyChangesDialog has a description apply path. This means description-only edits never produce pending changes (so Apply/Discard actions do not appear), and description updates are skipped even when applying other fields.
Useful? React with 👍 / 👎.
| <div class="flex gap-1 mb-3"> | ||
| <button class="btn btn-xs btn-success flex-1" :disabled="actionLoading" @click="handleVmAction('start')">Start</button> | ||
| <button class="btn btn-xs btn-warning flex-1" :disabled="actionLoading" @click="handleVmAction('stop')">Stop</button> | ||
| <button class="btn btn-xs btn-info flex-1" :disabled="actionLoading" @click="handleVmAction('pause')">Pause</button> |
There was a problem hiding this comment.
Handle pause action in VM action switch
The deployed VM panel now renders a Pause button that calls handleVmAction('pause'), but the action switch has no pause branch. In this flow, clicking Pause performs no VM command and silently acts like a no-op, so users cannot actually pause a running VM from this control.
Useful? React with 👍 / 👎.
| </span> | ||
| <button | ||
| class="text-[9px] font-medium text-amber-600 dark:text-amber-400 hover:text-amber-800 dark:hover:text-amber-200" | ||
| @click.stop="emit('open-apply-dialog')" |
There was a problem hiding this comment.
Wire pending-change Apply strip to a real handler
The new node-level pending-changes strip emits open-apply-dialog, but there is no listener wired for that event in the VM node host path (the node-vm slot currently just renders <InfraNodeVm v-bind="props" />). As a result, the Apply button shown on the node card does nothing when clicked.
Useful? React with 👍 / 👎.
- usePendingChanges: include 'description' in DIFFABLE_FIELDS so description-only edits register as pending changes and get applied (P1) - ConfigPanel: add pause/resume cases to handleVmAction so the Pause button is no longer a no-op (P2) - ProjectEditor: wire the node-card Apply strip's open-apply-dialog event to open the node's ConfigPanel and surface the apply dialog (P2); ConfigPanel exposes openApplyDialog() for this
What
Adds a VM configuration drift feature: an editable ConfigPanel for deployed VMs that tracks desired vs actual config, surfaces per-field drift, and applies changes through an orchestrated dialog.
usePendingChangesdiff engine (+ tests) andchangeCategoriesmapping (+ tests)ApplyChangesDialogwith categorized changes and orchestrated applydesiredConfig/actualConfigstate initialized on deploy/import; WebSocket status writes toactualConfigsetName/setDescription/setCpu/setMemoryAPI methods (+ setTags path fix)Integration
This branch was based on the pre-v1
dev. Currentdev(the v1 line) has been merged in and conflicts resolved:ConfigPanel.vue: kept both the pending-changes wiring and v1's confirm/toast usage; feature verified wired (usePendingChanges called, ApplyChangesDialog in template, drift bound across fields).vite.config.js: took dev's canonical config (callback form + dev-gated devtools + proxy/worker).api.ts/deploymentStore.ts/ProjectEditor.vue: auto-merged.Verification
Note for review
ConfigPanel.vue is a large auto-merge of two heavy rewrites; it compiles, lints, and tests green, but a visual QA pass of the deployed-VM edit/apply/revert flow is recommended before merge.