Refresh tabs/presets UI and add a mobile menu.

This improves navigation and profile workflows on smaller screens.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-08 13:51:09 +13:00
parent 6c6ed22dbe
commit d907ca37ad
6 changed files with 917 additions and 379 deletions

View File

@@ -73,6 +73,70 @@ document.addEventListener("DOMContentLoaded", () => {
}
});
const cloneButton = document.createElement("button");
cloneButton.className = "btn btn-secondary btn-small";
cloneButton.textContent = "Clone";
cloneButton.addEventListener("click", async () => {
const baseName = (profile && profile.name) || profileId;
const suggested = `${baseName}`;
const name = prompt("New profile name:", suggested);
if (name === null) {
return;
}
const trimmed = String(name).trim();
if (!trimmed) {
alert("Profile name cannot be empty.");
return;
}
try {
const response = await fetch(`/profiles/${profileId}/clone`, {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({ name: trimmed }),
});
if (!response.ok) {
throw new Error("Failed to clone profile");
}
const data = await response.json().catch(() => null);
let newProfileId = null;
if (data && typeof data === "object") {
if (data.id) {
newProfileId = String(data.id);
} else {
const ids = Object.keys(data);
if (ids.length > 0) {
newProfileId = String(ids[0]);
}
}
}
if (newProfileId) {
await fetch(`/profiles/${newProfileId}/apply`, {
method: "POST",
headers: { Accept: "application/json" },
});
}
document.cookie = "current_tab=; path=/; max-age=0";
await loadProfiles();
if (typeof window.loadTabs === "function") {
await window.loadTabs();
}
if (typeof window.loadTabsModal === "function") {
await window.loadTabsModal();
}
const tabContent = document.getElementById("tab-content");
if (tabContent) {
tabContent.innerHTML = `
<div class="tab-content-placeholder">
Select a tab to get started
</div>
`;
}
} catch (error) {
console.error("Clone profile failed:", error);
alert("Failed to clone profile.");
}
});
const deleteButton = document.createElement("button");
deleteButton.className = "btn btn-danger btn-small";
deleteButton.textContent = "Delete";
@@ -98,6 +162,7 @@ document.addEventListener("DOMContentLoaded", () => {
row.appendChild(label);
row.appendChild(applyButton);
row.appendChild(cloneButton);
row.appendChild(deleteButton);
profilesList.appendChild(row);
});
@@ -150,8 +215,44 @@ document.addEventListener("DOMContentLoaded", () => {
if (!response.ok) {
throw new Error("Failed to create profile");
}
const data = await response.json().catch(() => null);
let newProfileId = null;
if (data && typeof data === "object") {
if (data.id) {
newProfileId = String(data.id);
} else {
const ids = Object.keys(data);
if (ids.length > 0) {
newProfileId = String(ids[0]);
}
}
}
if (newProfileId) {
await fetch(`/profiles/${newProfileId}/apply`, {
method: "POST",
headers: { Accept: "application/json" },
});
}
newProfileInput.value = "";
// Clear current tab and refresh the UI so the new profile starts empty.
document.cookie = "current_tab=; path=/; max-age=0";
await loadProfiles();
if (typeof window.loadTabs === "function") {
await window.loadTabs();
}
if (typeof window.loadTabsModal === "function") {
await window.loadTabsModal();
}
const tabContent = document.getElementById("tab-content");
if (tabContent) {
tabContent.innerHTML = `
<div class="tab-content-placeholder">
Select a tab to get started
</div>
`;
}
} catch (error) {
console.error("Create profile failed:", error);
alert("Failed to create profile.");