Skip to content

Commit 76d67b9

Browse files
fix(ui): improve edit control ux, no layout shift, consistent spacing (#122)
1 parent 1a6f731 commit 76d67b9

5 files changed

Lines changed: 91 additions & 33 deletions

File tree

‎ui/src/core/page-components/agent-detail/modals/edit-control/evaluator-config-section.tsx‎

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { EvaluatorJsonView } from './evaluator-json-view';
1717
import type { ConfigViewMode } from './types';
1818

1919
const DEFAULT_HEIGHT = 450;
20+
const CONTENT_MIN_HEIGHT_EXTRA = 60;
2021
type ValidationStatus = 'idle' | 'validating' | 'valid' | 'invalid';
2122

2223
type EvaluatorConfigSectionProps = {
@@ -72,6 +73,8 @@ export function EvaluatorConfigSection({
7273
? 'red'
7374
: 'dimmed';
7475

76+
const contentHeight = height + CONTENT_MIN_HEIGHT_EXTRA;
77+
7578
return (
7679
<Stack gap="md">
7780
<Group justify="space-between" align="center">
@@ -91,45 +94,44 @@ export function EvaluatorConfigSection({
9194
</Group>
9295
</Anchor>
9396
</Group>
94-
<SegmentedControl
95-
value={configViewMode}
96-
onChange={handleConfigViewModeChange}
97-
disabled={configViewMode === 'json' && !!jsonError}
98-
data={[
99-
{ value: 'form', label: 'Form' },
100-
{ value: 'json', label: 'JSON' },
101-
]}
102-
size="xs"
103-
/>
97+
<Group gap="xs" align="center">
98+
{statusLabel ? (
99+
<Text size="xs" c={statusColor}>
100+
{statusLabel}
101+
</Text>
102+
) : null}
103+
<SegmentedControl
104+
value={configViewMode}
105+
onChange={handleConfigViewModeChange}
106+
disabled={configViewMode === 'json' && !!jsonError}
107+
data={[
108+
{ value: 'form', label: 'Form' },
109+
{ value: 'json', label: 'JSON' },
110+
]}
111+
size="xs"
112+
/>
113+
</Group>
104114
</Group>
105-
{statusLabel ? (
106-
<Text size="xs" c={statusColor}>
107-
{statusLabel}
108-
</Text>
109-
) : null}
110-
111115
<Paper withBorder radius="sm" p={16}>
112-
{configViewMode === 'form' && (
113-
<ScrollArea h={height} type="auto">
114-
{FormComponent ? (
116+
<ScrollArea h={contentHeight} type="always" offsetScrollbars="y">
117+
{configViewMode === 'form' ? (
118+
FormComponent ? (
115119
<FormComponent form={evaluatorForm} />
116120
) : (
117121
<Text c="dimmed" ta="center" py="xl">
118122
No form available for this evaluator. Use JSON view to
119123
configure.
120124
</Text>
121-
)}
122-
</ScrollArea>
123-
)}
124-
125-
{configViewMode === 'json' && (
126-
<EvaluatorJsonView
127-
onValidateConfig={onValidateConfig}
128-
onValidationStatusChange={setValidationStatus}
129-
height={height}
130-
{...jsonViewProps}
131-
/>
132-
)}
125+
)
126+
) : (
127+
<EvaluatorJsonView
128+
onValidateConfig={onValidateConfig}
129+
onValidationStatusChange={setValidationStatus}
130+
height={height}
131+
{...jsonViewProps}
132+
/>
133+
)}
134+
</ScrollArea>
133135
</Paper>
134136
</Stack>
135137
);

‎ui/src/core/page-components/agent-detail/modals/edit-control/evaluator-json-view.tsx‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { useDebouncedValue } from '@mantine/hooks';
33
import { useEffect, useRef } from 'react';
44

55
import { isApiError } from '@/core/api/errors';
6+
import {
7+
labelPropsInline,
8+
LabelWithTooltip,
9+
} from '@/core/components/label-with-tooltip';
610

711
import { ApiErrorAlert } from './api-error-alert';
812
import type { EvaluatorJsonViewProps } from './types';
@@ -79,6 +83,13 @@ export const EvaluatorJsonView = ({
7983
return (
8084
<Box>
8185
<Textarea
86+
label={
87+
<LabelWithTooltip
88+
label="Configuration (JSON)"
89+
tooltip="Raw evaluator configuration in JSON format"
90+
/>
91+
}
92+
labelProps={labelPropsInline}
8293
value={jsonText}
8394
onChange={(e) => handleJsonChange(e.currentTarget.value)}
8495
styles={{

‎ui/src/core/page-components/agent-detail/modals/edit-control/step-name-input.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function StepNameInput({ form, steps = [] }: StepNameInputProps) {
9999

100100
return (
101101
<Box>
102-
<Group gap="xs" mb={4} wrap="nowrap">
102+
<Group gap="xs" mb={8} wrap="nowrap">
103103
<Group gap={4}>
104104
<Text size="sm" fw={500}>
105105
Step name

‎ui/src/pages/_app.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { LoginModal } from '@/core/components/login-modal';
2424
import { AuthProvider, useAuth } from '@/core/providers/auth-provider';
2525
import { QueryProvider } from '@/core/providers/query-provider';
2626
import type { NextPageWithLayout } from '@/core/types/page';
27+
import { appTheme } from '@/theme';
2728

2829
type AppPropsWithLayout = AppProps & {
2930
Component: NextPageWithLayout;
@@ -125,7 +126,7 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
125126

126127
<ErrorBoundary variant="page">
127128
<QueryProvider>
128-
<MantineProvider defaultColorScheme="auto">
129+
<MantineProvider theme={appTheme} defaultColorScheme="auto">
129130
<Notifications />
130131
<DatesProvider settings={{ firstDayOfWeek: 0 }}>
131132
<JupiterThemeProvider>

‎ui/src/theme.ts‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
Autocomplete,
3+
createTheme,
4+
MultiSelect,
5+
NumberInput,
6+
Select,
7+
TagsInput,
8+
Textarea,
9+
TextInput,
10+
} from '@mantine/core';
11+
12+
const LABEL_INPUT_GAP = 8;
13+
14+
const formInputLabelStyles = {
15+
label: {
16+
marginBottom: LABEL_INPUT_GAP,
17+
},
18+
};
19+
20+
export const appTheme = createTheme({
21+
components: {
22+
TextInput: TextInput.extend({
23+
styles: formInputLabelStyles,
24+
}),
25+
Textarea: Textarea.extend({
26+
styles: formInputLabelStyles,
27+
}),
28+
Select: Select.extend({
29+
styles: formInputLabelStyles,
30+
}),
31+
MultiSelect: MultiSelect.extend({
32+
styles: formInputLabelStyles,
33+
}),
34+
Autocomplete: Autocomplete.extend({
35+
styles: formInputLabelStyles,
36+
}),
37+
TagsInput: TagsInput.extend({
38+
styles: formInputLabelStyles,
39+
}),
40+
NumberInput: NumberInput.extend({
41+
styles: formInputLabelStyles,
42+
}),
43+
},
44+
});

0 commit comments

Comments
 (0)