feat(ui): redesign job workspace sections

This commit is contained in:
cesnimda
2026-10-07 01:58:31 +02:00
parent acd1d94684
commit ac6d78289d
123 changed files with 2842 additions and 205 deletions
+17 -1
View File
@@ -9,6 +9,7 @@ import { I18nProvider } from './i18n/I18nProvider';
import { api } from './api';
jest.mock('./api', () => ({
getApiErrorMessage: (_error: unknown, fallback: string) => fallback,
api: {
get: jest.fn(),
post: jest.fn(),
@@ -19,6 +20,8 @@ jest.mock('./api', () => ({
const mockedApi = api as jest.Mocked<typeof api>;
beforeEach(() => jest.clearAllMocks());
test('attachments empty state renders drag and drop guidance', async () => {
mockedApi.get.mockResolvedValueOnce({ data: [] } as any);
@@ -35,7 +38,7 @@ test('attachments empty state renders drag and drop guidance', async () => {
);
expect(await screen.findByText(/drag and drop files here/i)).toBeInTheDocument();
expect(screen.getByText(/no attachments yet/i)).toBeInTheDocument();
expect(await screen.findByText(/no attachments yet/i)).toBeInTheDocument();
expect(screen.getByText(/max 10 mb each/i)).toBeInTheDocument();
});
@@ -72,6 +75,8 @@ test('attachments metadata controls update purpose and ai usage', async () => {
expect(screen.getByRole('button', { name: 'Download: resume.pdf' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Rename: resume.pdf' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Delete: resume.pdf' })).toBeInTheDocument();
expect(screen.getAllByRole('columnheader')).toHaveLength(8);
expect(screen.getByRole('columnheader', { name: 'Uploaded' })).toBeInTheDocument();
fireEvent.mouseDown(screen.getByRole('combobox', { name: /purpose/i }));
fireEvent.click(await screen.findByRole('option', { name: /portfolio/i }));
@@ -86,3 +91,14 @@ test('attachments metadata controls update purpose and ai usage', async () => {
expect(mockedApi.patch).toHaveBeenCalledWith('/attachments/7', expect.objectContaining({ purpose: 'portfolio', useForAi: false }));
});
});
test('attachment failures remain explicit and retry restores the real empty state', async () => {
mockedApi.get.mockRejectedValueOnce({ response: { status: 503 } }).mockResolvedValueOnce({ data: [] } as any);
render(<ToastProvider><I18nProvider><ConfirmProvider><PromptProvider><Attachments jobId={42} /></PromptProvider></ConfirmProvider></I18nProvider></ToastProvider>);
expect(await screen.findByRole('alert')).toHaveTextContent("Could not load this application's attachments.");
expect(screen.queryByText(/no attachments yet/i)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Retry' }));
expect(await screen.findByText(/no attachments yet/i)).toBeInTheDocument();
expect(mockedApi.get).toHaveBeenCalledTimes(2);
expect(mockedApi.post).not.toHaveBeenCalled();
});