Skip to content

Fix editability of some data-lake variables#2776

Open
rafaellehmkuhl wants to merge 5 commits into
bluerobotics:masterfrom
rafaellehmkuhl:fix-camera-speed-variables-not-editable
Open

Fix editability of some data-lake variables#2776
rafaellehmkuhl wants to merge 5 commits into
bluerobotics:masterfrom
rafaellehmkuhl:fix-camera-speed-variables-not-editable

Conversation

@rafaellehmkuhl

Copy link
Copy Markdown
Member

Fix #2774
Fix #2775

@github-actions

Copy link
Copy Markdown

Automated PR Review (Claude)

0. Summary

Verdict: MINOR SUGGESTIONS

Minor items to consider: 1.1, 1.2, 6.1.

This PR fixes editability of certain data-lake variables (camera zoom/focus speed). It introduces a "value-only edit mode" in DataLakeVariableDialog for variables that have allowUserToChangeValue: true but are not user-defined (persistent !== true). It also fixes isUserDefinedVariable to use strict === true instead of != null (which incorrectly matched persistent: false), adds persistValue: true to the speed variables so their values survive reboots, and restores persisted values when createDataLakeVariable is called for persistValue variables. Fixes #2774 and #2775.

1. Correctness & Implementation Bugs

1.1 minor — In src/libs/actions/data-lake.ts, the new code in createDataLakeVariable loads the saved value when variable.persistValue is true, but then unconditionally overwrites the timestamp check and savePersistentValues() call below using the original initialValue variable (not valueToSet):

if (initialValue !== undefined) {
    dataLakeVariableTimestamps[variable.id] = performance.now()
}
...
if (variable.persistValue && initialValue !== undefined) {
    savePersistentValues()
}

When a persisted value exists and initialValue is also provided (which is the case for camera speed variables — initialValue is 3), the timestamp will be set and savePersistentValues() will be called — both fine. However, the savePersistentValues() call will re-save the just-loaded value, which is harmless but slightly wasteful. More importantly, if initialValue were undefined but a persisted value existed, the timestamp would never be set. This is a minor correctness gap in an edge case that likely doesn't occur today, but consider using valueToSet instead of initialValue in the subsequent conditions for consistency.

1.2 minor — In DataLakeVariableDialog.vue, the valueOnlyEditMode computed checks variableInfo?.persistent !== true, which means a variable with persistent: undefined would enter value-only edit mode if it has allowUserToChangeValue: true. This is the intended behavior for the camera speed variables, but it's worth noting that if a user-defined variable were to have both persistent: true and allowUserToChangeValue: true, it would bypass value-only mode and get the full edit form (which is correct). The logic is sound for the current use cases.

2. AGENTS.md Adherence — ✅

3. Security — ✅

4. Performance — ✅

5. UI / UX — ✅

6. Code Quality & Style

6.1 nit — In ToolsDataLakeView.vue, the function editUserDefinedVariable was renamed to editVariable and its JSDoc was not updated to reflect its new broader scope. The current doc says "Opens the dialog to edit an existing variable" which is still accurate, but the @param description and the error-path message Variable with ID ${variableId} is not editable no longer match the broadened condition. This is minor since the JSDoc was already generic, but the snackbar message now only triggers for variables that are neither user-defined nor user-editable, which is correct.

7. Commit Hygiene — ✅

8. Tests — ✅

9. Documentation — ✅

10. Nitpicks / Optional — ✅

Generated by Claude. This is advisory; a human reviewer must still approve.

Internal variables with persistValue were always initialized from their default, overwriting values saved in localStorage.
Only zoom/focus speed settings should be configurable by the user; increase/decrease variables remain internal-only.
The Data Lake table hid the edit button for internal variables even when they were marked as user-editable.
Editing internal variables should only change the value, not metadata like name, type, or persistence settings.
Internal variables explicitly marked persistent:false were shown as user-defined in the Data Lake, allowing full edit and delete.
@rafaellehmkuhl rafaellehmkuhl force-pushed the fix-camera-speed-variables-not-editable branch from adef72e to e1b8787 Compare June 17, 2026 12:54
@rafaellehmkuhl

Copy link
Copy Markdown
Member Author

Review follow-up — round 1

Done

  • src/libs/actions/data-lake.ts (1.1 — use valueToSet for timestamp/persist checks): timestamp init and savePersistentValues() now key off valueToSet !== undefined instead of initialValue, so a persisted value loaded without an explicit default still gets a timestamp.
  • src/views/ToolsDataLakeView.vue (6.1 — editVariable JSDoc): updated to say it opens the dialog for user-defined or user-editable variables.

Done differently

  • src/components/DataLakeVariableDialog.vue (1.2 — value-only edit guard): no longer uses persistent !== true; value-only mode now checks !isUserDefinedDataLakeVariable(), with the helper living in src/libs/utils-data-lake.ts (IDs under user/custom/, or userDefined: true).

Won't change (with reasoning)

  • 1.2 — value-only mode for persistent: undefined: intentional; camera speed vars are internal but user-editable, and user-defined vars from the Data Lake menu get the full edit form.

@rafaellehmkuhl

Copy link
Copy Markdown
Member Author

/review

@github-actions

Copy link
Copy Markdown

Automated PR Re-review 2 (Claude)

Comparing adef72e1917865cd10a70f36d92aa58ca21fef6ae1b8787d06e61b0354f3bce50782e7bcab25d6c8. Note: the incremental diff includes unrelated changes from a rebase onto master (CI workflows, mission estimates, package.json). This re-check is based on the pr.diff (base...head) for accuracy.

Previous findings status

# Finding Severity Status
1.1 data-lake.ts: use valueToSet instead of initialValue in timestamp/persist checks minor ✅ Addressed
1.2 DataLakeVariableDialog.vue: valueOnlyEditMode guard using persistent !== true minor ✅ Addressed
6.1 ToolsDataLakeView.vue: JSDoc not updated for renamed editVariable nit ✅ Addressed

Discussion since last review

@rafaellehmkuhl posted a review follow-up detailing how each finding was handled:

  • 1.1: timestamp init and savePersistentValues() now key off valueToSet — confirmed addressed in the diff.
  • 1.2: Done differently — value-only mode now checks !isUserDefinedDataLakeVariable() instead of persistent !== true, using a new helper. This is a cleaner approach.
  • 6.1: JSDoc updated — confirmed.

New findings

0. Summary

Verdict: MINOR SUGGESTIONS

Minor items to consider: 1.1, 6.1.

This PR fixes editability of certain data-lake variables (camera zoom/focus speed). It introduces a userDefined flag on DataLakeVariable, a centralized isUserDefinedDataLakeVariable helper, a "value-only edit mode" in DataLakeVariableDialog for internal but user-editable variables, and restores persisted values inside createDataLakeVariable. All previous findings have been addressed. Two minor new items surfaced.

1. Correctness & Implementation Bugs

1.1 minor — In src/libs/utils-data-lake.ts, the isUserDefinedDataLakeVariable function checks info?.userDefined === true or normalizedId.startsWith(userDefinedDataLakeVariableIdPrefix) (i.e. 'user/custom/'). However, existing user-created variables (from before this PR) were never stamped with userDefined: true — they were identified solely by having persistent != null. After this PR, isUserDefinedVariable in ToolsDataLakeView.vue delegates to isUserDefinedDataLakeVariable, which relies on the userDefined flag or the user/custom/ prefix. Since the base code auto-generates IDs with the 'user/custom/' + machinizeString(name) prefix (line 186 of DataLakeVariableDialog.vue), existing variables created through the UI will match the prefix check, so this is safe in the normal flow. However, if a user manually edited the ID (via the pencil toggle) to something that doesn't start with user/custom/, and it was created before this PR (so it has no userDefined: true flag), that variable will no longer be recognized as user-defined and will lose its edit/delete buttons. This is a narrow edge case but worth noting.

2. AGENTS.md Adherence — ✅

3. Security — ✅

4. Performance — ✅

5. UI / UX — ✅

6. Code Quality & Style

6.1 nit — In src/libs/utils-data-lake.ts, normalizeDataLakeVariableId is a private helper that only strips leading whitespace and slashes. Given that the user/custom/ prefix is set programmatically by machinizeString, leading whitespace and slashes in an ID would be unusual. The helper isn't wrong, but it does defensive work that may never be exercised. Consider whether it adds enough value or if a direct id.startsWith(userDefinedDataLakeVariableIdPrefix) would suffice.

7. Commit Hygiene — ✅

8. Tests — ✅

9. Documentation — ✅

10. Nitpicks / Optional — ✅

Generated by Claude. This is advisory; a human reviewer must still approve.

@rafaellehmkuhl

Copy link
Copy Markdown
Member Author

Review follow-up — round 2

All round 1 findings (1.1, 1.2, 6.1) were confirmed addressed in the re-review. Two new minor items this round — declining both, reasoning below.

Won't change (with reasoning)

  • 1.1 — pre-PR menu variables with a manually-edited custom ID losing edit/delete: real but unfixable cleanly. Going forward, menu-created variables are stamped userDefined: true, and the default auto-generated IDs use the user/custom/ prefix, so the normal flow is safe. For old persisted data there's no way to retroactively distinguish a Data-Lake-menu variable with a custom ID from a user/inputs/ input-element variable (both are persistent: true with no userDefined flag) — so a migration stamp on load would wrongly promote input-element variables to full user-defined and hand them delete buttons, which contradicts the intended "user-defined = created in the Data Lake menu only" rule. The affected case (pre-PR + menu-created + manually overridden ID) is very narrow and such variables still keep value editing through allowUserToChangeValue.
  • 6.1 — normalizeDataLakeVariableId defensive trimming: intentional. The leading-space/slash normalization before the prefix check is a deliberate, explicitly requested behavior so IDs like user/custom/x or //user/custom/x still resolve as user-defined; keeping it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Several internal variables are being treated as "user defined" Speed variables for camera zoom and focus should be editable, but are not

1 participant