|
1 | | -import type { RuntimeMode } from "@t3tools/contracts"; |
| 1 | +import type { EnvironmentId, RuntimeMode } from "@t3tools/contracts"; |
2 | 2 | import { useAtomValue } from "@effect/atom-react"; |
3 | 3 |
|
4 | 4 | import { shortcutLabelForCommand } from "../keybindings"; |
| 5 | +import { useManagedPolicy } from "../state/managedPolicy"; |
5 | 6 | import { primaryServerKeybindingsAtom } from "../state/server"; |
6 | 7 | import { ComposerControl } from "./chat/ComposerControl"; |
7 | | -import { runtimeModeConfig } from "./chat/runtimeModeConfig"; |
| 8 | +import { ComposerPermissionsSection } from "./chat/ComposerFooterControls"; |
| 9 | +import { useComposerMenuProps } from "./chat/composerEventScope"; |
| 10 | +import { |
| 11 | + resolveCompatibleRuntimeMode, |
| 12 | + resolveRuntimeModeOptions, |
| 13 | + runtimeModeConfig, |
| 14 | +} from "./chat/runtimeModeConfig"; |
8 | 15 | import { ComposerContextLabel } from "./ComposerContextLabel"; |
| 16 | +import { Menu, MenuPopup, MenuTrigger } from "./ui/menu"; |
9 | 17 | import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; |
10 | 18 |
|
11 | | -/** The new-thread strip names the permissions the first send will use; clicking opens them. */ |
12 | 19 | export function ComposerContextPermissions(props: { |
| 20 | + environmentId: EnvironmentId | null; |
13 | 21 | runtimeMode: RuntimeMode; |
14 | | - onOpen: () => void; |
| 22 | + supportedRuntimeModes: ReadonlyArray<RuntimeMode> | undefined; |
| 23 | + onRuntimeModeChange: (mode: RuntimeMode) => void; |
15 | 24 | }) { |
16 | 25 | const shortcutLabel = shortcutLabelForCommand( |
17 | 26 | useAtomValue(primaryServerKeybindingsAtom), |
18 | 27 | "composer.mode", |
19 | 28 | ); |
20 | | - const { icon: Icon, label } = runtimeModeConfig[props.runtimeMode]; |
| 29 | + const { mode, modes } = resolveCompatibleRuntimeMode( |
| 30 | + props.runtimeMode, |
| 31 | + props.supportedRuntimeModes, |
| 32 | + ); |
| 33 | + const options = resolveRuntimeModeOptions(modes, useManagedPolicy(props.environmentId)); |
| 34 | + const composerMenuProps = useComposerMenuProps(); |
| 35 | + const { icon: Icon, label } = runtimeModeConfig[mode]; |
21 | 36 | return ( |
22 | | - <Tooltip> |
23 | | - <TooltipTrigger |
24 | | - render={ |
25 | | - <ComposerControl |
26 | | - size="xs" |
27 | | - className="ms-auto min-w-0 shrink-0" |
28 | | - aria-label={`Permissions: ${label}`} |
29 | | - aria-haspopup="menu" |
30 | | - data-composer-context-control |
31 | | - onClick={props.onOpen} |
32 | | - /> |
33 | | - } |
34 | | - > |
35 | | - <Icon aria-hidden="true" className="size-3" /> |
36 | | - <ComposerContextLabel>{label}</ComposerContextLabel> |
37 | | - </TooltipTrigger> |
38 | | - <TooltipPopup>Permissions{shortcutLabel ? ` · ${shortcutLabel}` : null}</TooltipPopup> |
39 | | - </Tooltip> |
| 37 | + <Menu> |
| 38 | + <Tooltip> |
| 39 | + <TooltipTrigger |
| 40 | + render={ |
| 41 | + <MenuTrigger |
| 42 | + render={ |
| 43 | + <ComposerControl |
| 44 | + size="xs" |
| 45 | + className="ms-auto min-w-0 shrink-0" |
| 46 | + aria-label={`Permissions: ${label}`} |
| 47 | + data-composer-context-control |
| 48 | + /> |
| 49 | + } |
| 50 | + /> |
| 51 | + } |
| 52 | + > |
| 53 | + <Icon aria-hidden="true" className="size-3" /> |
| 54 | + <ComposerContextLabel>{label}</ComposerContextLabel> |
| 55 | + </TooltipTrigger> |
| 56 | + <TooltipPopup>Permissions{shortcutLabel ? ` · ${shortcutLabel}` : null}</TooltipPopup> |
| 57 | + </Tooltip> |
| 58 | + <MenuPopup side="top" align="end" {...composerMenuProps}> |
| 59 | + <ComposerPermissionsSection |
| 60 | + runtimeMode={mode} |
| 61 | + runtimeModeOptions={options} |
| 62 | + onRuntimeModeChange={props.onRuntimeModeChange} |
| 63 | + /> |
| 64 | + </MenuPopup> |
| 65 | + </Menu> |
40 | 66 | ); |
41 | 67 | } |
0 commit comments