Skip to content

Allow pre-selecting vehicle, version, and board via URL parameters#229

Open
ryanbasic1 wants to merge 2 commits intoArduPilot:mainfrom
ryanbasic1:feature/url-preselect-clean
Open

Allow pre-selecting vehicle, version, and board via URL parameters#229
ryanbasic1 wants to merge 2 commits intoArduPilot:mainfrom
ryanbasic1:feature/url-preselect-clean

Conversation

@ryanbasic1
Copy link

Adds support for pre-selecting vehicle, version, and board from URL parameters.

Example:

?vehicle=copter&version=stable&board=pixhawk

Details

Frontend-only change
No backend changes required
Safe fallback if parameters are invalid
Does not affect existing behavior

This allows external links to directly open pre-configured build ### ### selections.

Closes #181

Adds support for pre-selecting vehicle, version, and board from URL parameters.

Example: ?vehicle=copter&version=stable&board=pixhawk

- Frontend-only change
- No backend changes
- Safe fallback if parameters are invalid
- Does not affect existing behavior

This allows external links to directly open pre-configured build selections.
@shiv-tyagi
Copy link
Member

shiv-tyagi commented Feb 14, 2026

This PR still has huge diff. I will suggest you to get to the root cause instead of resubmitting the PR.

Do not close existing PR. The same branch after fixing things in this PR itself.

You need to get rid of your last commit I think.

Please check diff before pushing.
Stop blindly trusting that AI please.

@ryanbasic1 ryanbasic1 force-pushed the feature/url-preselect-clean branch from f39ece1 to 9a111be Compare February 14, 2026 18:29
Copy link
Member

@shiv-tyagi shiv-tyagi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing. The direction is correct. It just needs a little more polishing. PTAL.

if (typeof rebuildFromBuildId !== 'undefined') {
await initRebuild(rebuildFromBuildId);
} else {
initFromUrlParams();
Copy link
Member

@shiv-tyagi shiv-tyagi Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename initRebuild to initPreSelect and do both in same function (and get rid of initFromUrlParams altogether). We first check if rebuild_from param is there, if not we check vehicle_id, board_id and version_id are present, and set those properties.

The only difference would be that we would not be setting selected_features[], in second case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I merged the rebuild and URL param logic into a single initPreSelect() function and removed initFromUrlParams().
Thank you

Comment on lines 323 to 325
if (params.has('vehicle')) rebuildConfig.vehicleId = params.get('vehicle');
if (params.has('board')) rebuildConfig.boardId = params.get('board');
if (params.has('version')) rebuildConfig.versionId = params.get('version');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (params.has('vehicle')) rebuildConfig.vehicleId = params.get('vehicle');
if (params.has('board')) rebuildConfig.boardId = params.get('board');
if (params.has('version')) rebuildConfig.versionId = params.get('version');
if (params.has('vehicle_id')) rebuildConfig.vehicleId = params.get('vehicle');
if (params.has('board_id')) rebuildConfig.boardId = params.get('board');
if (params.has('version_id')) rebuildConfig.versionId = params.get('version');

Let us call it vehicle_id and similar at all places.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use vehicle_id, version_id and board_id consistently for URL parameters.

Thanks for pointing this out.

if (params.has('version')) rebuildConfig.versionId = params.get('version');

// Set flag to indicate URL parameters were provided
rebuildConfig.fromUrlParams = hasParams;
Copy link
Member

@shiv-tyagi shiv-tyagi Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be avoided? This won't be needed if we have a common error handling as described in the other comment.

Comment on lines 419 to 429
if (rebuildConfig.isRebuildMode) {
console.warn(`Rebuild vehicle '${rebuildConfig.vehicleId}' not found in available vehicles`);
alert(`Warning: The vehicle from the original build is no longer available.\n\nRedirecting to new build page...`);
window.location.href = '/add_build';
return;
} else if (rebuildConfig.fromUrlParams) {
console.warn(`URL parameter vehicle '${rebuildConfig.vehicleId}' not found. Defaulting to first available vehicle.`);
rebuildConfig.vehicleId = null;
} else {
rebuildConfig.vehicleId = null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have one common error message for both cases? That way we can also avoid multiple if-else cases.

Maybe something like, "Vehicle XXX is no longer listed for building. Redirecting to new build page...".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes added a common error message for both case ! ###

Comment on lines 531 to 541
if (rebuildConfig.isRebuildMode) {
console.warn(`Rebuild board '${rebuildConfig.boardId}' not found for version '${version_id}'`);
alert(`Warning: The board from the original build is no longer available.\n\nRedirecting to new build page...`);
window.location.href = '/add_build';
return;
} else if (rebuildConfig.fromUrlParams) {
console.warn(`URL parameter board '${rebuildConfig.boardId}' not found for version '${version_id}'. Defaulting to first available board.`);
rebuildConfig.boardId = null;
} else {
rebuildConfig.boardId = null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the other comment for vehicles.

Comment on lines 468 to 478
if (rebuildConfig.isRebuildMode) {
console.warn(`Rebuild version '${rebuildConfig.versionId}' not found for vehicle '${new_vehicle_id}'`);
alert(`Warning: The version from the original build is no longer available.\n\nRedirecting to new build page...`);
window.location.href = '/add_build';
return;
} else if (rebuildConfig.fromUrlParams) {
console.warn(`URL parameter version '${rebuildConfig.versionId}' not found for vehicle '${new_vehicle_id}'. Defaulting to first available version.`);
rebuildConfig.versionId = null;
} else {
rebuildConfig.versionId = null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the other comment for vehicles.

function updateGlobalCheckboxState() {
const total_options = Object.keys(features_by_id).length;
let global_checkbox = document.getElementById("check-uncheck-all");
if (!global_checkbox) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

async function initPreSelect() {
const params = new URLSearchParams(window.location.search);

// Rebuild flow ---
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Rebuild flow ---

const params = new URLSearchParams(window.location.search);

// Rebuild flow ---
if (typeof rebuildFromBuildId !== "undefined") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use params.has() and params.get() here as well.

Comment on lines +334 to +336
alert(
"Failed to load build configuration.\n\nRedirecting to new build page..."
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
alert(
"Failed to load build configuration.\n\nRedirecting to new build page..."
);
alert(
"Failed to load build configuration: " + error.message + "\n\nRedirecting to new build page..."
);

Comment on lines +327 to +331
rebuildConfig.vehicleId = data.vehicle?.id || null;
rebuildConfig.versionId = data.version?.id || null;
rebuildConfig.boardId = data.board?.id || null;
rebuildConfig.selectedFeatures = data.selected_features || [];
rebuildConfig.isRebuildMode = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't just fallback to null like this. See existing pattern and throw similar error to the user.


const data = await res.json();

rebuildConfig.vehicleId = data.vehicle?.id || null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should call it preSelectConfig now.

for (let i=0; i<all_collapse_elements.length; i+=1) {
let collapse_element = all_collapse_elements[i];
collapse_instance = bootstrap.Collapse.getOrCreateInstance(collapse_element);
let collapse_instance = bootstrap.Collapse.getOrCreateInstance(collapse_element);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let collapse_instance = bootstrap.Collapse.getOrCreateInstance(collapse_element);
collapse_instance = bootstrap.Collapse.getOrCreateInstance(collapse_element);

Not in this PR


function createCategoryCard(category_name, features_in_category, expanded) {
options_html = "";
let options_html = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope of this PR. Please remove this.

output.innerHTML = '<label for="vehicle" class="form-label"><strong>Select Vehicle</strong></label>' +
'<select name="vehicle" id="vehicle" class="form-select" aria-label="Select Vehicle" onchange="onVehicleChange(this.value);"></select>';
vehicleList = document.getElementById("vehicle");
let vehicleList = document.getElementById("vehicle");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope of this PR.

let vehicleList = document.getElementById("vehicle");
vehicles.forEach(vehicle => {
opt = document.createElement('option');
let opt = document.createElement('option');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope of this PR.

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.

Allow passing vehicle, version and board in HTTP request to pre-select options in the dropdowns

2 participants

Comments