Files
sim-link/src/lib/SimulationSidebar.svelte

187 lines
5.5 KiB
Svelte

<script lang="ts">
import type { SimulationState } from "./simulationState.svelte";
let { state }: { state: SimulationState } = $props();
async function clearFails() {
if (
!confirm(
"Are you sure you want to permanently delete all failed simulations?",
)
) {
return;
}
try {
const res = await fetch("/api/simulations/clear-fails", {
method: "DELETE",
});
if (res.ok) {
const data = await res.json();
alert(
`Successfully cleared ${data.deleted_count} failed runs.`,
);
window.location.reload();
} else {
alert("Failed to clear simulations.");
}
} catch (e) {
console.error("Error clearing fails:", e);
alert("Network error clearing fails.");
}
}
</script>
<aside class="sidebar">
<details open class="filter-group">
<summary>Search & Sort</summary>
<div class="filter-content">
<input
type="text"
placeholder="Search ID..."
bind:value={state.searchQuery}
class="input-field full-width"
/>
<select bind:value={state.sortOrder} class="input-field full-width">
<option value="newest">Newest First</option>
<option value="oldest">Oldest First</option>
<option value="fastest">Fastest</option>
<option value="slowest">Slowest</option>
</select>
</div>
</details>
<details class="filter-group">
<summary>Algorithm Pattern</summary>
<div class="filter-content">
<select
bind:value={state.filterPattern}
class="input-field full-width"
>
<option value="any">Any</option>
<option value="spiral">Spiral</option>
<option value="lawnmower">Lawnmower</option>
<option value="levy">Levy</option>
</select>
</div>
</details>
<details class="filter-group">
<summary>Date Range</summary>
<div class="filter-content col">
<label
>From <input
type="date"
bind:value={state.filterDateFrom}
class="input-field"
/></label
>
<label
>To <input
type="date"
bind:value={state.filterDateTo}
class="input-field"
/></label
>
</div>
</details>
<details class="filter-group">
<summary>Flight Altitude</summary>
<div class="filter-content col">
<label
>Min (ft) <input
type="number"
step="0.1"
bind:value={state.filterAltMin}
class="input-field small-num"
/></label
>
<label
>Max (ft) <input
type="number"
step="0.1"
bind:value={state.filterAltMax}
class="input-field small-num"
/></label
>
</div>
</details>
<details class="filter-group">
<summary>UAV Speed</summary>
<div class="filter-content col">
<label
>Min (mph) <input
type="number"
step="0.1"
bind:value={state.filterUavMin}
class="input-field small-num"
/></label
>
<label
>Max (mph) <input
type="number"
step="0.1"
bind:value={state.filterUavMax}
class="input-field small-num"
/></label
>
</div>
</details>
<details class="filter-group">
<summary>UGV Speed</summary>
<div class="filter-content col">
<label
>Min (mph) <input
type="number"
step="0.1"
bind:value={state.filterUgvMin}
class="input-field small-num"
/></label
>
<label
>Max (mph) <input
type="number"
step="0.1"
bind:value={state.filterUgvMax}
class="input-field small-num"
/></label
>
</div>
</details>
<button class="reset-btn" onclick={() => state.resetFilters()}>
Reset Filters
</button>
<button class="clear-fails-btn" onclick={clearFails}> Clear Fails </button>
</aside>
<style>
.reset-btn,
.clear-fails-btn {
width: 100%;
margin-top: 20px;
padding: 10px;
background-color: #e0e0e0;
border: 1px solid #000;
font-weight: bold;
font-size: 14px;
font-family: inherit;
cursor: pointer;
text-transform: uppercase;
}
.reset-btn:hover {
background-color: #d0d0d0;
}
.clear-fails-btn {
margin-top: 10px;
background-color: #ffcccc;
color: #990000;
border-color: #990000;
}
.clear-fails-btn:hover {
background-color: #ff9999;
}
</style>