Compare commits
2 Commits
af68e8923c
...
be844bc4d0
| Author | SHA256 | Date | |
|---|---|---|---|
| be844bc4d0 | |||
| a90824efcd |
16303
package-lock.json
generated
16303
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,14 +4,15 @@
|
|||||||
"chartjs-plugin-annotation": "^3.1.0"
|
"chartjs-plugin-annotation": "^3.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.15.31",
|
"@types/node": "^22.16.3",
|
||||||
"parcel": "^2.15.2",
|
"autoprefixer": "^10.4.21",
|
||||||
|
"parcel": "^2.15.4",
|
||||||
|
"postcss": "^8.5.6",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "parcel src/roast.html",
|
"start": "parcel src/roast.html",
|
||||||
"build": "parcel build src/roast.html --public-url=./ --dist-dir dist"
|
"build": "parcel build src/roast.html --public-url=./ --dist-dir dist"
|
||||||
|
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
|||||||
@@ -13,7 +13,23 @@
|
|||||||
<div id="create-plan">
|
<div id="create-plan">
|
||||||
<input type="text" id="plan-input" placeholder="Enter temperatures (comma separated)">
|
<input type="text" id="plan-input" placeholder="Enter temperatures (comma separated)">
|
||||||
<button onclick="setPlan()">Set Plan</button>
|
<button onclick="setPlan()">Set Plan</button>
|
||||||
|
|
||||||
|
<!-- Save and Load Plan UI -->
|
||||||
|
<div id="plan-storage" style="margin-top: 16px;">
|
||||||
|
<input type="text" id="save-name" placeholder="Save plan as..." style="width: 60%; padding: 8px;">
|
||||||
|
<button onclick="saveCurrentPlan()" style="padding: 8px 16px;">Save Plan</button>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<button onclick="clearSavedPlans()" style="margin-top: 10px; padding: 6px 16px;">Clear All Plans</button>
|
||||||
|
|
||||||
|
<label for="saved-plans">Load a saved plan:</label>
|
||||||
|
<select id="saved-plans" onchange="loadSavedPlan(this.value)" style="margin-left: 8px; padding: 6px;">
|
||||||
|
<option value="">-- Select saved plan --</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="controls" class="hidden">
|
<div id="controls" class="hidden">
|
||||||
<div id="temp-buttons" class="button-group"></div>
|
<div id="temp-buttons" class="button-group"></div>
|
||||||
<div id="event-buttons" class="button-group">
|
<div id="event-buttons" class="button-group">
|
||||||
|
|||||||
88
src/roast.ts
88
src/roast.ts
@@ -21,9 +21,13 @@ declare global {
|
|||||||
exportCSV: () => void;
|
exportCSV: () => void;
|
||||||
showGraph: () => void;
|
showGraph: () => void;
|
||||||
hideGraph: () => void;
|
hideGraph: () => void;
|
||||||
|
saveCurrentPlan: () => void;
|
||||||
|
loadSavedPlan: (name: string) => void;
|
||||||
|
clearSavedPlans: () => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function startTimer(): void {
|
function startTimer(): void {
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
alert("Timer is already running. Click again to reset.");
|
alert("Timer is already running. Click again to reset.");
|
||||||
@@ -263,9 +267,87 @@ function hideGraph(): void {
|
|||||||
graphContainer.classList.add("hidden");
|
graphContainer.classList.add("hidden");
|
||||||
graphContainer.classList.remove("graph-display-flex");
|
graphContainer.classList.remove("graph-display-flex");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose functions to the global scope (allowing html direct access)
|
function saveCurrentPlan(): void {
|
||||||
|
const nameInput = document.getElementById("save-name") as HTMLInputElement;
|
||||||
|
const planName = nameInput.value.trim();
|
||||||
|
const rawInput = (document.getElementById("plan-input") as HTMLInputElement).value.trim();
|
||||||
|
|
||||||
|
if (!planName) {
|
||||||
|
alert("Please enter a name to save the plan.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rawInput) {
|
||||||
|
alert("Temperature list is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = rawInput.split(',').map(x => x.trim()).map(Number);
|
||||||
|
if (parsed.some(val => isNaN(val))) {
|
||||||
|
alert("Invalid temperature list. Please enter comma-separated numbers.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempStr = parsed.join(",");
|
||||||
|
localStorage.setItem(`roastplan_${planName}`, tempStr);
|
||||||
|
nameInput.value = "";
|
||||||
|
updateSavedPlansDropdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function loadSavedPlan(name: string): void {
|
||||||
|
if (!name) return;
|
||||||
|
const stored = localStorage.getItem(`roastplan_${name}`);
|
||||||
|
if (stored) {
|
||||||
|
targets = stored.split(",").map(Number);
|
||||||
|
currentTargetIndex = 0;
|
||||||
|
document.getElementById("controls")!.classList.remove("hidden");
|
||||||
|
document.getElementById("create-plan")!.classList.add("hidden");
|
||||||
|
generateTempButtons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSavedPlansDropdown(): void {
|
||||||
|
const dropdown = document.getElementById("saved-plans") as HTMLSelectElement;
|
||||||
|
dropdown.innerHTML = '<option value="">-- Select saved plan --</option>';
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i);
|
||||||
|
if (key && key.startsWith("roastplan_")) {
|
||||||
|
const name = key.replace("roastplan_", "");
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = name;
|
||||||
|
option.textContent = name;
|
||||||
|
dropdown.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSavedPlans(): void {
|
||||||
|
const confirmClear = confirm("Are you sure you want to delete all saved roast plans?");
|
||||||
|
if (!confirmClear) return;
|
||||||
|
|
||||||
|
const keysToRemove: string[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i);
|
||||||
|
if (key && key.startsWith("roastplan_")) {
|
||||||
|
keysToRemove.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keysToRemove.forEach(key => localStorage.removeItem(key));
|
||||||
|
updateSavedPlansDropdown();
|
||||||
|
alert("All saved roast plans have been deleted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
updateSavedPlansDropdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Include in window export
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.startTimer = startTimer;
|
window.startTimer = startTimer;
|
||||||
window.stopTimer = stopTimer;
|
window.stopTimer = stopTimer;
|
||||||
@@ -277,6 +359,10 @@ if (typeof window !== 'undefined') {
|
|||||||
window.exportCSV = exportCSV;
|
window.exportCSV = exportCSV;
|
||||||
window.showGraph = showGraph;
|
window.showGraph = showGraph;
|
||||||
window.hideGraph = hideGraph;
|
window.hideGraph = hideGraph;
|
||||||
|
window.saveCurrentPlan = saveCurrentPlan;
|
||||||
|
window.loadSavedPlan = loadSavedPlan;
|
||||||
|
window.clearSavedPlans = clearSavedPlans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
Reference in New Issue
Block a user