import { useCreateEnvironment } from '../hooks/useCreateEnvironment'; import { useEnvironments } from '../hooks/useEnvironments'; import type { Environment, Workspace } from '../lib/models'; import { Button } from './core/Button'; import classNames from 'classnames'; import { PairEditor } from './core/PairEditor'; import type { PairEditorProps } from './core/PairEditor'; import { useCallback, useMemo, useState } from 'react'; import { useUpdateEnvironment } from '../hooks/useUpdateEnvironment'; import { HStack, VStack } from './core/Stacks'; import { IconButton } from './core/IconButton'; import { useDeleteEnvironment } from '../hooks/useDeleteEnvironment'; import type { DropdownItem } from './core/Dropdown'; import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; import { usePrompt } from '../hooks/usePrompt'; import { InlineCode } from './core/InlineCode'; import { useWindowSize } from 'react-use'; import type { GenericCompletionConfig, GenericCompletionOption, } from './core/Editor/genericCompletion'; import { useActiveWorkspace } from '../hooks/useActiveWorkspace'; import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace'; interface Props { initialEnvironment: Environment | null; } export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { const [selectedEnvironmentId, setSelectedEnvironmentId] = useState( initialEnvironment?.id ?? null, ); const environments = useEnvironments(); const createEnvironment = useCreateEnvironment(); const activeWorkspace = useActiveWorkspace(); const windowSize = useWindowSize(); const showSidebar = windowSize.width > 500; const selectedEnvironment = useMemo( () => environments.find((e) => e.id === selectedEnvironmentId) ?? null, [environments, selectedEnvironmentId], ); return (
{showSidebar && ( )} {activeWorkspace != null ? ( ) : (
select an environment
)}
); }; const EnvironmentEditor = function ({ environment, workspace, }: { environment: Environment | null; workspace: Workspace; }) { const environments = useEnvironments(); const updateEnvironment = useUpdateEnvironment(environment?.id ?? 'n/a'); const updateWorkspace = useUpdateWorkspace(workspace.id); const deleteEnvironment = useDeleteEnvironment(environment); const variables = environment == null ? workspace.variables : environment.variables; const handleChange = useCallback( (variables) => { if (environment != null) { updateEnvironment.mutate({ variables }); } else { updateWorkspace.mutate({ variables }); } }, [updateWorkspace, updateEnvironment, environment], ); // Gather a list of env names from other environments, to help the user get them aligned const nameAutocomplete = useMemo(() => { const otherEnvironments = environments.filter((e) => e.id !== environment?.id); const allVariableNames = environment == null ? [ // Nothing to autocomplete if we're in the base environment ] : [ ...workspace.variables.map((v) => v.name), ...otherEnvironments.flatMap((e) => e.variables.map((v) => v.name)), ]; // Filter out empty strings and variables that already exist const variableNames = allVariableNames.filter( (name) => name != '' && !variables.find((v) => v.name === name), ); const uniqueVariableNames = [...new Set(variableNames)]; const options = uniqueVariableNames.map( (name): GenericCompletionOption => ({ label: name, type: 'constant', }), ); return { options }; }, [environments, variables, workspace, environment]); const prompt = usePrompt(); const items = useMemo( () => environment == null ? null : [ { key: 'rename', label: 'Rename', leftSlot: , onSelect: async () => { const name = await prompt({ title: 'Rename Environment', description: ( <> Enter a new name for {environment.name} ), name: 'name', label: 'Name', defaultValue: environment.name, }); updateEnvironment.mutate({ name }); }, }, { key: 'delete', variant: 'danger', label: 'Delete', leftSlot: , onSelect: () => deleteEnvironment.mutate(), }, ], [deleteEnvironment, updateEnvironment, prompt, environment], ); const validateName = useCallback((name: string) => { // Empty just means the variable doesn't have a name yet, and is unusable if (name === '') return true; return name.match(/^[a-z_][a-z0-9_]*$/i) != null; }, []); return (

{environment?.name ?? 'Base Environment'}

{items != null && ( )}
); }; function SidebarButton({ children, className, active, onClick, }: { className?: string; children: string; active: boolean; onClick: () => void; }) { return ( ); }