blanchon's picture
Update
3cdf7b9
<script lang="ts">
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import * as DropdownMenu from "@/components/ui/dropdown-menu";
import { toast } from "svelte-sonner";
import { cn } from "$lib/utils";
import { videoManager } from "$lib/elements/video/VideoManager.svelte";
interface Props {
open: boolean;
}
let { open = $bindable() }: Props = $props();
interface SensorConfig {
id: string;
label: string;
description: string;
icon: string;
enabled: boolean;
isDefault?: boolean;
}
const sensorConfigs: SensorConfig[] = [
{
id: 'camera',
label: 'Camera',
description: 'Video Camera Sensor',
icon: 'icon-[mdi--camera]',
enabled: true,
isDefault: true
},
{
id: 'lidar',
label: 'Lidar',
description: 'Distance Sensor',
icon: 'icon-[mdi--radar]',
enabled: false
},
{
id: 'imu',
label: 'IMU',
description: 'Motion Sensor',
icon: 'icon-[mdi--radar]',
enabled: false
}
];
async function addSensor(sensorType: string) {
try {
// Basic validation
if (!sensorType) return;
const sensorId = `${sensorType}_${Date.now()}`;
if (sensorType === "camera") {
// Create video camera
const video = videoManager.createVideo(sensorId);
toast.success("Video Camera Added", {
description: `Video camera ${sensorId.slice(0, 12)}... created successfully.`
});
} else {
// Placeholder for other sensor types
const config = sensorConfigs.find(c => c.id === sensorType);
toast.success("Sensor Added", {
description: `${config?.label || sensorType} sensor ${sensorId.slice(0, 12)}... created successfully.`
});
}
open = false; // Close dropdown on success
} catch (error) {
console.error("Sensor creation failed:", error);
toast.error("Failed to Add Sensor", {
description: `Could not create ${sensorType} sensor: ${error}`
});
}
}
async function quickAddCamera() {
await addSensor("camera");
}
</script>
<!-- Main Add Button (Camera) -->
<Button
variant="default"
size="sm"
onclick={quickAddCamera}
class="group rounded-r-none border-0 bg-blue-500 text-white transition-all duration-200 hover:bg-blue-400 dark:bg-blue-600 dark:hover:bg-blue-500"
>
<span
class={[
"mr-2 size-4 transition-transform duration-200",
"icon-[mdi--plus] group-hover:rotate-90"
]}
></span>
Add Sensor
</Button>
<!-- Dropdown Menu Button -->
<DropdownMenu.Root bind:open>
<DropdownMenu.Trigger >
{#snippet child({ props })}
<Button
{...props}
variant="default"
size="sm"
class={cn(
"rounded-l-none border-0 border-l border-blue-400/30 bg-blue-500 px-2 text-white transition-all duration-200 hover:bg-blue-400",
"dark:border-blue-500/30 dark:bg-blue-600 dark:hover:bg-blue-500",
open && "bg-blue-600 shadow-inner dark:bg-blue-700"
)}
>
<span
class={cn(
"size-4 transition-transform duration-200",
"icon-[mdi--chevron-down]",
open && "rotate-180"
)}
></span>
</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content
class="w-56 border-blue-400/30 bg-blue-500 backdrop-blur-sm dark:border-blue-500/30 dark:bg-blue-600"
align="center"
>
<DropdownMenu.Group>
<DropdownMenu.GroupHeading
class="text-xs font-semibold tracking-wider text-blue-100 uppercase dark:text-blue-200"
>
Sensor Types
</DropdownMenu.GroupHeading>
{#each sensorConfigs as sensor}
<DropdownMenu.Item
class={[
"group group cursor-pointer bg-blue-500 text-white transition-all duration-200",
"data-highlighted:bg-blue-600 dark:bg-blue-600 dark:data-highlighted:bg-blue-700"
]}
disabled={!sensor.enabled}
onclick={async () => await addSensor(sensor.id)}
>
<span
class={[
sensor.icon,
"mr-3 size-4 text-blue-100 transition-colors duration-200 dark:text-blue-200"
]}
></span>
<div class="flex flex-1 flex-col">
<span class="font-medium text-white transition-colors duration-200"
>{sensor.label}</span
>
<span class="text-xs text-blue-100 transition-colors duration-200 dark:text-blue-200">
{sensor.description}
</span>
</div>
{#if sensor.isDefault}
<Badge
variant="secondary"
class="ml-2 bg-blue-600 text-xs text-blue-100 group-data-highlighted:bg-blue-300 group-data-highlighted:text-blue-900 dark:bg-blue-700 dark:text-blue-100 dark:group-data-highlighted:bg-blue-400 dark:group-data-highlighted:text-blue-900"
>
Default
</Badge>
{/if}
</DropdownMenu.Item>
{/each}
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>