Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 70 additions & 53 deletions web/static/js/add_build.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ const Features = (() => {
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?



let indeterminate_state = false;
switch (selected_options) {
Expand Down Expand Up @@ -306,45 +308,54 @@ var rebuildConfig = {
};

async function init() {
if (typeof rebuildFromBuildId !== 'undefined') {
await initRebuild(rebuildFromBuildId);
}

fetchVehicles();
await initPreSelect();
fetchVehicles();
}

async function initRebuild(buildId) {

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 ---

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.

try {
const buildResponse = await fetch(`/api/v1/builds/${buildId}`);
if (!buildResponse.ok) {
throw new Error('Failed to fetch build details');
}
const buildData = await buildResponse.json();

if (!buildData.vehicle || !buildData.vehicle.id) {
throw new Error('Vehicle information is missing from the build');
}
if (!buildData.version || !buildData.version.id) {
throw new Error('Version information is missing from the build');
}
if (!buildData.board || !buildData.board.id) {
throw new Error('Board information is missing from the build');
}

rebuildConfig.vehicleId = buildData.vehicle.id;
rebuildConfig.versionId = buildData.version.id;
rebuildConfig.boardId = buildData.board.id;
rebuildConfig.selectedFeatures = buildData.selected_features || [];
rebuildConfig.isRebuildMode = true;

} catch (error) {
console.error('Error loading rebuild configuration:', error);
alert('Failed to load build configuration: ' + error.message + '\n\nRedirecting to new build page...');
window.location.href = '/add_build';
throw error;
}
const res = await fetch(`/api/v1/builds/${rebuildFromBuildId}`);
if (!res.ok) throw new Error("Failed to fetch build");

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.

rebuildConfig.versionId = data.version?.id || null;
rebuildConfig.boardId = data.board?.id || null;
rebuildConfig.selectedFeatures = data.selected_features || [];
rebuildConfig.isRebuildMode = true;
Comment on lines +327 to +331
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.

} catch (err) {
console.error("Error loading rebuild config:", err);
alert(
"Failed to load build configuration.\n\nRedirecting to new build page..."
);
Comment on lines +334 to +336
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..."
);

window.location.href = "/add_build";
throw err;
}

return;
}

// ===== URL PARAM 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
// ===== URL PARAM FLOW =====

if (params.has("vehicle_id")) {
rebuildConfig.vehicleId = params.get("vehicle_id");
}

if (params.has("version_id")) {
rebuildConfig.versionId = params.get("version_id");
}

if (params.has("board_id")) {
rebuildConfig.boardId = params.get("board_id");
}
}


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

function applyRebuildFeatures(featuresList) {
Features.checkUncheckAll(false);

Expand All @@ -361,6 +372,7 @@ function clearRebuildConfig() {
rebuildConfig.boardId = null;
rebuildConfig.selectedFeatures = [];
rebuildConfig.isRebuildMode = false;

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

}

// enables or disables the elements with ids passed as an array
Expand Down Expand Up @@ -400,11 +412,13 @@ function fetchVehicles() {
if (rebuildConfig.vehicleId) {
const vehicleExists = all_vehicles.some(v => v.id === rebuildConfig.vehicleId);
if (!vehicleExists) {
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;
}
const msg = `Vehicle '${rebuildConfig.vehicleId}' is no longer listed for building. Redirecting to new build page...`;
console.warn(msg);
alert(msg);
window.location.href = '/add_build';
return;
}

}

let new_vehicle = rebuildConfig.vehicleId ||
Expand Down Expand Up @@ -441,12 +455,14 @@ function onVehicleChange(new_vehicle_id) {

if (rebuildConfig.versionId) {
const versionExists = all_versions.some(v => v.id === rebuildConfig.versionId);
if (!versionExists) {
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;
}
if (!versionExists) {
const msg = `Version '${rebuildConfig.versionId}' is no longer listed for building. Redirecting to new build page...`;
console.warn(msg);
alert(msg);
window.location.href = '/add_build';
return;
}

}

const new_version = rebuildConfig.versionId || all_versions[0].id;
Expand Down Expand Up @@ -498,13 +514,14 @@ function onVersionChange(new_version) {
if (rebuildConfig.boardId) {
const boardExists = boards.some(b => b.id === rebuildConfig.boardId);
if (!boardExists) {
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...`);
const msg = `Board '${rebuildConfig.boardId}' is no longer listed for building. Redirecting to new build page...`;
console.warn(msg);
alert(msg);
window.location.href = '/add_build';
return;
}
}

}

let new_board = rebuildConfig.boardId || (boards.length > 0 ? boards[0].id : null);
updateBoards(boards, new_board);
})
Expand Down Expand Up @@ -583,7 +600,7 @@ var toggle_all_categories = (() => {

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

if (all_categories_expanded && !collapse_element.classList.contains('show')) {
collapse_instance.show();
} else if (!all_categories_expanded && collapse_element.classList.contains('show')) {
Expand All @@ -596,7 +613,7 @@ var toggle_all_categories = (() => {
})();

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.

features_in_category.forEach(feature => {
options_html += '<div class="form-check">' +
'<input class="form-check-input feature-checkbox" type="checkbox" value="1" name="'+feature.id+'" id="'+feature.id+'" onclick="Features.handleOptionStateChange(this.id, true);">' +
Expand Down Expand Up @@ -708,9 +725,9 @@ function fillVehicles(vehicles, vehicle_id_to_select) {
var output = document.getElementById('vehicle_list');
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.

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.

opt.value = vehicle.id;
opt.innerHTML = vehicle.name;
opt.selected = (vehicle.id === vehicle_id_to_select);
Expand Down