/** The "Macro recording" status bar item and the Edit Macros dialog. */ import { useState } from "react"; import { create } from "zustand"; import { executeAction, getAction } from "@/platform/actions"; import { t, tx } from "@/platform/i18n"; import { BarButton, Button, Dialog, Icon, List, T } from "@/ui"; import { confirm } from "@/workbench/messages"; import { promptInput } from "@/workbench/inputDialogs"; import { deleteMacro, describeStep, renameMacro, useMacros } from "./model"; import styles from "./macros.module.css"; const useEditOpen = create<{ open: boolean }>(() => ({ open: false })); export const showEditMacros = () => useEditOpen.setState({ open: true }); const actionTitle = (id: string) => getAction(id)?.title ?? id; /** Shown while recording (IDEA: "Macro recording started" in the status bar); click stops. */ export function MacroStatus() { const steps = useMacros((s) => s.recording?.length); if (steps === undefined) return null; return ( void executeAction("macro.stopRecording")} > Recording macro… ); } export function MacrosDialogHost() { const open = useEditOpen((s) => s.open); return open ? useEditOpen.setState({ open: false })} /> : null; } function EditMacrosDialog({ onClose }: { onClose: () => void }) { const saved = useMacros((s) => s.saved); const [active, setActive] = useState(0); const macro = saved[Math.min(active, saved.length - 1)]; const rename = async () => { if (!macro) return; const name = await promptInput({ title: "Rename Macro", label: "New name:", initial: macro.name, okLabel: "Rename", validate: (v) => !v.trim() ? "Enter a macro name" : v.trim() !== macro.name && saved.some((m) => m.name === v.trim()) ? "A macro with this name exists" : null, }); if (name) renameMacro(macro.name, name); }; const remove = async () => { if (!macro) return; if (await confirm({ title: "Delete Macro", message: tx`Delete the macro '${macro.name}'?`, ok: "Delete", icon: "warning" })) deleteMacro(macro.name); }; return ( m.name} activeIndex={Math.min(active, saved.length - 1)} onActiveChange={setActive} rowHeight={24} className={styles.list} aria-label="Macros" empty={ No saved macros } renderItem={(m) => {m.name}} /> void rename()}> Rename… void remove()}> Delete {macro?.steps.map((step, i) => ( {describeStep(step, actionTitle)} ))} ); }