({ onSuccess }: AddPluginDialogProps)
| 313 | } |
| 314 | |
| 315 | export function AddPluginDialog({ onSuccess }: AddPluginDialogProps) { |
| 316 | const [open, setOpen] = useState(false); |
| 317 | const [name, setName] = useState(""); |
| 318 | const [fileType, setFileType] = useState<"js" | "ts">("ts"); |
| 319 | const [template, setTemplate] = useState<TemplateLock>("basic"); |
| 320 | const [content, setContent] = useState(PLUGIN_TEMPLATES.basic.ts); |
| 321 | const [error, setError] = useState(""); |
| 322 | const [loading, setLoading] = useState(false); |
| 323 | const [fetching, setFetching] = useState(false); |
| 324 | const [urlInput, setUrlInput] = useState(""); |
| 325 | const [configImporting, setConfigImporting] = useState(false); |
| 326 | |
| 327 | const resetForm = () => { |
| 328 | setName(""); |
| 329 | setFileType("ts"); |
| 330 | setTemplate("basic"); |
| 331 | setContent(PLUGIN_TEMPLATES.basic.ts); |
| 332 | setError(""); |
| 333 | setUrlInput(""); |
| 334 | }; |
| 335 | |
| 336 | const handleTypeChange = (type: "js" | "ts") => { |
| 337 | setFileType(type); |
| 338 | setContent(PLUGIN_TEMPLATES[template][type]); |
| 339 | }; |
| 340 | |
| 341 | const handleTemplateChange = (newTemplate: TemplateLock) => { |
| 342 | setTemplate(newTemplate); |
| 343 | setContent(PLUGIN_TEMPLATES[newTemplate][fileType]); |
| 344 | }; |
| 345 | |
| 346 | const handleConfigPaste = async (plugins: string[]) => { |
| 347 | try { |
| 348 | setConfigImporting(true); |
| 349 | setError(""); |
| 350 | const result = await addPluginsToConfig(plugins); |
| 351 | |
| 352 | if (result.added.length > 0) { |
| 353 | toast.success(`Added ${result.added.length} plugin(s) to config`); |
| 354 | } |
| 355 | if (result.skipped.length > 0) { |
| 356 | toast.info(`Skipped ${result.skipped.length} already existing`); |
| 357 | } |
| 358 | |
| 359 | resetForm(); |
| 360 | setOpen(false); |
| 361 | onSuccess(); |
| 362 | } catch (err) { |
| 363 | setError(err instanceof Error ? err.message : "Failed to add plugins to config"); |
| 364 | } finally { |
| 365 | setConfigImporting(false); |
| 366 | } |
| 367 | }; |
| 368 | |
| 369 | const handleFetchUrl = async () => { |
| 370 | if (!urlInput.trim()) return; |
| 371 | |
| 372 | const configPlugins = tryParsePluginConfig(urlInput); |
nothing calls this directly
no test coverage detected