diff --git a/src/components/Config/EditTangibleInline.tsx b/src/components/Config/EditTangibleInline.tsx index 4cadb7a..d0f3b3e 100644 --- a/src/components/Config/EditTangibleInline.tsx +++ b/src/components/Config/EditTangibleInline.tsx @@ -1,7 +1,8 @@ -import { useState, useEffect, KeyboardEvent } from 'react'; -import SaveIcon from '@mui/icons-material/Save'; -import TangibleForm from './TangibleForm'; -import type { TangibleConfig, TangibleMode, LabelConfig, ConstellationState } from '../../types'; +import { useState, useEffect, KeyboardEvent } from "react"; +import SaveIcon from "@mui/icons-material/Save"; +import TangibleForm from "./TangibleForm"; +import type { TangibleConfig, TangibleMode, LabelConfig } from "../../types"; +import type { ConstellationState } from "../../types/timeline"; interface Props { tangible: TangibleConfig; @@ -16,28 +17,34 @@ interface Props { hardwareId?: string; filterLabels?: string[]; stateId?: string; - } + }, ) => void; onCancel: () => void; } -const EditTangibleInline = ({ tangible, labels, states, onSave, onCancel }: Props) => { - const [name, setName] = useState(''); - const [mode, setMode] = useState('filter'); - const [description, setDescription] = useState(''); - const [hardwareId, setHardwareId] = useState(''); +const EditTangibleInline = ({ + tangible, + labels, + states, + onSave, + onCancel, +}: Props) => { + const [name, setName] = useState(""); + const [mode, setMode] = useState("filter"); + const [description, setDescription] = useState(""); + const [hardwareId, setHardwareId] = useState(""); const [filterLabels, setFilterLabels] = useState([]); - const [stateId, setStateId] = useState(''); + const [stateId, setStateId] = useState(""); // Sync state with tangible prop useEffect(() => { if (tangible) { setName(tangible.name); setMode(tangible.mode); - setDescription(tangible.description || ''); - setHardwareId(tangible.hardwareId || ''); + setDescription(tangible.description || ""); + setHardwareId(tangible.hardwareId || ""); setFilterLabels(tangible.filterLabels || []); - setStateId(tangible.stateId || ''); + setStateId(tangible.stateId || ""); } }, [tangible]); @@ -45,12 +52,12 @@ const EditTangibleInline = ({ tangible, labels, states, onSave, onCancel }: Prop if (!name.trim()) return; // Validate mode-specific fields - if (mode === 'filter' && filterLabels.length === 0) { - alert('Filter mode requires at least one label'); + if (mode === "filter" && filterLabels.length === 0) { + alert("Filter mode requires at least one label"); return; } - if ((mode === 'state' || mode === 'stateDial') && !stateId) { - alert('State mode requires a state selection'); + if ((mode === "state" || mode === "stateDial") && !stateId) { + alert("State mode requires a state selection"); return; } @@ -59,16 +66,16 @@ const EditTangibleInline = ({ tangible, labels, states, onSave, onCancel }: Prop mode, description: description.trim() || undefined, hardwareId: hardwareId.trim() || undefined, - filterLabels: mode === 'filter' ? filterLabels : undefined, - stateId: (mode === 'state' || mode === 'stateDial') ? stateId : undefined, + filterLabels: mode === "filter" ? filterLabels : undefined, + stateId: mode === "state" || mode === "stateDial" ? stateId : undefined, }); }; const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { + if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); handleSave(); - } else if (e.key === 'Escape') { + } else if (e.key === "Escape") { e.preventDefault(); onCancel(); } @@ -117,9 +124,13 @@ const EditTangibleInline = ({ tangible, labels, states, onSave, onCancel }: Prop {/* Keyboard Shortcut Hint */}
- {navigator.platform.includes('Mac') ? 'Cmd' : 'Ctrl'}+Enter - {' '} - to save, Esc to cancel + {navigator.platform.includes("Mac") ? "Cmd" : "Ctrl"}+Enter + {" "} + to save,{" "} + + Esc + {" "} + to cancel
diff --git a/src/components/Config/QuickAddTangibleForm.tsx b/src/components/Config/QuickAddTangibleForm.tsx index 4ac8934..47d3206 100644 --- a/src/components/Config/QuickAddTangibleForm.tsx +++ b/src/components/Config/QuickAddTangibleForm.tsx @@ -1,6 +1,7 @@ -import { useState, useRef, KeyboardEvent } from 'react'; -import TangibleForm from './TangibleForm'; -import type { TangibleMode, LabelConfig, ConstellationState } from '../../types'; +import { useState, useRef, KeyboardEvent } from "react"; +import TangibleForm from "./TangibleForm"; +import type { TangibleMode, LabelConfig } from "../../types"; +import type { ConstellationState } from "../../types/timeline"; interface Props { labels: LabelConfig[]; @@ -16,12 +17,12 @@ interface Props { } const QuickAddTangibleForm = ({ labels, states, onAdd }: Props) => { - const [name, setName] = useState(''); - const [hardwareId, setHardwareId] = useState(''); - const [mode, setMode] = useState('filter'); - const [description, setDescription] = useState(''); + const [name, setName] = useState(""); + const [hardwareId, setHardwareId] = useState(""); + const [mode, setMode] = useState("filter"); + const [description, setDescription] = useState(""); const [filterLabels, setFilterLabels] = useState([]); - const [stateId, setStateId] = useState(''); + const [stateId, setStateId] = useState(""); const nameInputRef = useRef(null); @@ -32,12 +33,12 @@ const QuickAddTangibleForm = ({ labels, states, onAdd }: Props) => { } // Validate mode-specific fields - if (mode === 'filter' && filterLabels.length === 0) { - alert('Filter mode requires at least one label'); + if (mode === "filter" && filterLabels.length === 0) { + alert("Filter mode requires at least one label"); return; } - if ((mode === 'state' || mode === 'stateDial') && !stateId) { - alert('State mode requires a state selection'); + if ((mode === "state" || mode === "stateDial") && !stateId) { + alert("State mode requires a state selection"); return; } @@ -46,33 +47,33 @@ const QuickAddTangibleForm = ({ labels, states, onAdd }: Props) => { mode, description, hardwareId: hardwareId.trim() || undefined, - filterLabels: mode === 'filter' ? filterLabels : undefined, - stateId: (mode === 'state' || mode === 'stateDial') ? stateId : undefined, + filterLabels: mode === "filter" ? filterLabels : undefined, + stateId: mode === "state" || mode === "stateDial" ? stateId : undefined, }); // Reset form - setName(''); - setHardwareId(''); - setMode('filter'); - setDescription(''); + setName(""); + setHardwareId(""); + setMode("filter"); + setDescription(""); setFilterLabels([]); - setStateId(''); + setStateId(""); nameInputRef.current?.focus(); }; const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Enter' && !e.shiftKey) { + if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSubmit(); - } else if (e.key === 'Escape') { + } else if (e.key === "Escape") { e.preventDefault(); - setName(''); - setHardwareId(''); - setMode('filter'); - setDescription(''); + setName(""); + setHardwareId(""); + setMode("filter"); + setDescription(""); setFilterLabels([]); - setStateId(''); + setStateId(""); nameInputRef.current?.blur(); } }; diff --git a/src/components/Config/TangibleForm.tsx b/src/components/Config/TangibleForm.tsx index 9081962..9160215 100644 --- a/src/components/Config/TangibleForm.tsx +++ b/src/components/Config/TangibleForm.tsx @@ -1,4 +1,5 @@ -import type { TangibleMode, LabelConfig, ConstellationState } from '../../types'; +import type { TangibleMode, LabelConfig } from "../../types"; +import type { ConstellationState } from "../../types/timeline"; interface Props { name: string; @@ -74,49 +75,60 @@ const TangibleForm = ({ type="radio" name="mode" value="filter" - checked={mode === 'filter'} + checked={mode === "filter"} onChange={(e) => onModeChange(e.target.value as TangibleMode)} className="mr-2" /> - Filter mode (activate label filters) + + Filter mode (activate label filters) + {/* Mode-specific fields */} - {mode === 'filter' && ( + {mode === "filter" && (
{labels.length === 0 ? ( -

No labels available

+

+ No labels available +

) : ( labels.map((label) => ( -
)} - {(mode === 'state' || mode === 'stateDial') && ( + {(mode === "state" || mode === "stateDial") && (