/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * BCFCreateTopicForm - New topic creation form for the BCF panel. * * Exposes the full BCF topic field set (type, status, priority, assignee, due * date, labels) plus an optional viewpoint snapshot preview. The snapshot * section only appears when the parent wires snapshot capture (`onCaptureSnapshot`), * since the image comes from the live WebGPU canvas the parent owns. */ import React, { useCallback, useState } from 'react'; import { X, Camera, RefreshCw, Loader2, ImageOff } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import type { BCFTopic } from '@ifc-lite/bcf'; import { TOPIC_TYPES, TOPIC_STATUSES, PRIORITIES } from './bcfHelpers'; // ============================================================================ // Types // ============================================================================ export interface BCFCreateTopicFormProps { onSubmit: (topic: Partial, options?: { includeSnapshot: boolean }) => void; onCancel: () => void; author: string; /** Pre-fill the title (e.g. when raising an issue from a detected change). */ initialTitle?: string; /** Pre-fill the description. */ initialDescription?: string; /** * Snapshot preview as a data URL. When this OR `onCaptureSnapshot` is provided * the form shows a viewpoint-snapshot section with an "attach" toggle. */ snapshot?: string | null; /** (Re)capture the viewpoint snapshot from the current view. */ onCaptureSnapshot?: () => void; /** True while a snapshot capture is in flight (shows a spinner, disables recapture). */ capturingSnapshot?: boolean; } // ============================================================================ // Component // ============================================================================ export function BCFCreateTopicForm({ onSubmit, onCancel, author: _author, initialTitle = '', initialDescription = '', snapshot, onCaptureSnapshot, capturingSnapshot = false, }: BCFCreateTopicFormProps) { const [title, setTitle] = useState(initialTitle); const [description, setDescription] = useState(initialDescription); const [topicType, setTopicType] = useState('Issue'); const [topicStatus, setTopicStatus] = useState('Open'); const [priority, setPriority] = useState('Medium'); const [assignedTo, setAssignedTo] = useState(''); const [dueDate, setDueDate] = useState(''); const [labels, setLabels] = useState(''); const [includeSnapshot, setIncludeSnapshot] = useState(true); // Snapshot is offered only when the parent can capture it from the canvas. const snapshotCapable = Boolean(onCaptureSnapshot); const handleSubmit = useCallback( (e: React.FormEvent) => { e.preventDefault(); if (!title.trim()) return; const parsedLabels = labels .split(',') .map((l) => l.trim()) .filter(Boolean); onSubmit( { title: title.trim(), description: description.trim() || undefined, topicType, topicStatus, priority, assignedTo: assignedTo.trim() || undefined, dueDate: dueDate || undefined, labels: parsedLabels.length ? parsedLabels : undefined, }, { includeSnapshot: snapshotCapable && includeSnapshot }, ); }, [title, description, topicType, topicStatus, priority, assignedTo, dueDate, labels, includeSnapshot, snapshotCapable, onSubmit], ); return (

New Topic

setTitle(e.target.value)} placeholder="Brief description of the issue" required />