1import {
2 AuthOrchestrationOperateScope,
3 type EditorId,
4 type EnvironmentId,
5} from "@t3tools/contracts";
6import { squashAtomCommandFailure } from "@t3tools/client-runtime/state/runtime";
7
8import { useOpenInPreferredEditor } from "../editorPreferences";
9import { useEnvironmentScope } from "../state/session";
10import { Button } from "./ui/button";
11import { stackedThreadToast, toastManager } from "./ui/toast";
12
13export function KeybindingsConfigWarning({
14 message,
15 environmentId,
16 configPath,
17 availableEditors,
18}: {
19 message: string;
20 environmentId: EnvironmentId | null;
21 configPath: string | null;
22 availableEditors: readonly EditorId[];
23}) {
24 const canOpenEditor = useEnvironmentScope(environmentId, AuthOrchestrationOperateScope);
25 const openInEditor = useOpenInPreferredEditor(environmentId, availableEditors);
26
27 return (
28 <>
29 {message}
30 <span className="mt-2 flex justify-end">
31 <Button
32 size="xs"
33 variant="outline"
34 disabled={!canOpenEditor || !configPath || availableEditors.length === 0}
35 onClick={async () => {
36 if (!configPath) return;
37 const result = await openInEditor(configPath);
38 if (result._tag === "Success") return;
39 const error = squashAtomCommandFailure(result);
40 toastManager.add(
41 stackedThreadToast({
42 type: "error",
43 title: "Unable to open keybindings file",
44 description: error instanceof Error ? error.message : "Unknown error opening file.",
45 }),
46 );
47 }}
48 >
49 Open keybindings.json
50 </Button>
51 </span>
52 </>
53 );
54}