Skip to content

Commit 2aeb0a1

Browse files
committed
place error at the top
1 parent c85b0f8 commit 2aeb0a1

3 files changed

Lines changed: 29 additions & 12 deletions

File tree

src/views/schedule-actions/schedule-actions-modal-content/__tests__/schedule-actions-modal-content.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jest.mock('next/navigation', () => ({
3333
describe(ScheduleActionsModalContent.name, () => {
3434
beforeEach(() => {
3535
jest.clearAllMocks();
36+
HTMLElement.prototype.scrollIntoView = jest.fn();
3637
});
3738

3839
it('renders the modal content as expected', async () => {
@@ -84,6 +85,9 @@ describe(ScheduleActionsModalContent.name, () => {
8485
await waitFor(() => {
8586
expect(screen.getByText('Failed to pause schedule')).toBeInTheDocument();
8687
});
88+
expect(HTMLElement.prototype.scrollIntoView).toHaveBeenCalledWith({
89+
block: 'start',
90+
});
8791
expect(mockOnClose).not.toHaveBeenCalled();
8892
});
8993
});

src/views/schedule-actions/schedule-actions-modal-content/schedule-actions-modal-content.styles.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ export const styled = {
1010
ModalBody: withStyle(ModalBody, ({ $theme }: { $theme: Theme }) => ({
1111
display: 'flex',
1212
flexDirection: 'column',
13+
rowGap: $theme.sizing.scale600,
1314
marginBottom: $theme.sizing.scale800,
15+
overflowY: 'auto',
16+
maxHeight: '70vh',
1417
})),
1518
ContextBanner: createStyled(
1619
'div',

src/views/schedule-actions/schedule-actions-modal-content/schedule-actions-modal-content.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { KIND as BUTTON_KIND, SIZE } from 'baseui/button';
55
import { ModalButton } from 'baseui/modal';
66
import { useSnackbar } from 'baseui/snackbar';
77
import { useRouter } from 'next/navigation';
8+
import { useEffect, useRef } from 'react';
89
import { type DefaultValues, type FieldValues, useForm } from 'react-hook-form';
910
import { MdCheckCircle, MdErrorOutline } from 'react-icons/md';
1011

@@ -30,6 +31,7 @@ export default function ScheduleActionsModalContent<
3031
const queryClient = useQueryClient();
3132
const router = useRouter();
3233
const { enqueue, dequeue } = useSnackbar();
34+
const errorAlertRef = useRef<HTMLDivElement>(null);
3335

3436
type OptionalFormData = FormData extends FieldValues ? FormData : FieldValues;
3537

@@ -85,6 +87,12 @@ export default function ScheduleActionsModalContent<
8587
queryClient
8688
);
8789

90+
useEffect(() => {
91+
if (error) {
92+
errorAlertRef.current?.scrollIntoView({ block: 'start' });
93+
}
94+
}, [error]);
95+
8896
const onSubmit = (data: OptionalFormData) => {
8997
mutate({
9098
...params,
@@ -115,6 +123,20 @@ export default function ScheduleActionsModalContent<
115123
<styled.ModalHeader>{`${action.label} schedule`}</styled.ModalHeader>
116124
<form onSubmit={handleSubmit(onSubmit)}>
117125
<styled.ModalBody>
126+
{error && (
127+
<div ref={errorAlertRef} role="alert">
128+
<Banner
129+
hierarchy={HIERARCHY.low}
130+
kind={BANNER_KIND.negative}
131+
overrides={overrides.banner}
132+
artwork={{
133+
icon: MdErrorOutline,
134+
}}
135+
>
136+
{error.message}
137+
</Banner>
138+
</div>
139+
)}
118140
{modalBanner ? (
119141
<styled.ContextBanner>{modalBanner}</styled.ContextBanner>
120142
) : null}
@@ -130,18 +152,6 @@ export default function ScheduleActionsModalContent<
130152
scheduleId={params.scheduleId}
131153
/>
132154
)}
133-
{error && (
134-
<Banner
135-
hierarchy={HIERARCHY.low}
136-
kind={BANNER_KIND.negative}
137-
overrides={overrides.banner}
138-
artwork={{
139-
icon: MdErrorOutline,
140-
}}
141-
>
142-
{error.message}
143-
</Banner>
144-
)}
145155
</styled.ModalBodyContent>
146156
</styled.ModalBody>
147157
<styled.ModalFooter>

0 commit comments

Comments
 (0)