From 694a7ea10caa207a0d711bbdf392c4aeb1921ac4 Mon Sep 17 00:00:00 2001 From: Aaron Chong Date: Wed, 18 Dec 2024 16:29:11 +0800 Subject: [PATCH] tasks-window Signed-off-by: Aaron Chong --- .../tasks/task-schedule-utils.test.ts | 15 ----- .../components/tasks/tasks-window.test.tsx | 48 ++++++++++++++ .../src/components/tasks/tasks-window.tsx | 63 +++++++++++-------- 3 files changed, 84 insertions(+), 42 deletions(-) create mode 100644 packages/rmf-dashboard-framework/src/components/tasks/tasks-window.test.tsx diff --git a/packages/rmf-dashboard-framework/src/components/tasks/task-schedule-utils.test.ts b/packages/rmf-dashboard-framework/src/components/tasks/task-schedule-utils.test.ts index f4da64a31..82d41aef6 100644 --- a/packages/rmf-dashboard-framework/src/components/tasks/task-schedule-utils.test.ts +++ b/packages/rmf-dashboard-framework/src/components/tasks/task-schedule-utils.test.ts @@ -482,18 +482,3 @@ describe('apiScheduleToSchedule', () => { expect(result.at).toEqual(new Date()); }); }); - -describe('toISOStringWithTimezone', () => { - it('should format date with positive timezone offset', () => { - const date = new Date('2023-10-27T01:00:00.000Z'); // UTC - const expectedOffset = '+08:00'; // Example: Singapore Time (UTC+8) - - // Mock the timezone offset of the date object. - const spy = vi.spyOn(date, 'getTimezoneOffset').mockImplementation(() => -480); // -480 minutes = +08:00 hours - - const result = toISOStringWithTimezone(date); - expect(result).toContain(expectedOffset); - expect(result).toEqual('2023-10-27T09:00:00+08:00'); - spy.mockRestore(); - }); -}); diff --git a/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.test.tsx b/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.test.tsx new file mode 100644 index 000000000..c479a28ff --- /dev/null +++ b/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.test.tsx @@ -0,0 +1,48 @@ +import { fireEvent, screen } from '@testing-library/react'; +import React, { act } from 'react'; +import { describe, expect, it, vi } from 'vitest'; + +import { RmfApiProvider } from '../../hooks'; +import { MockRmfApi, render, TestProviders } from '../../utils/test-utils.test'; +import { AppEvents } from '../app-events'; +import { TasksWindow } from './tasks-window'; + +vi.mock('../app-events', () => ({ + AppEvents: { + refreshTaskApp: { + subscribe: vi.fn(() => ({ unsubscribe: vi.fn() })), + next: vi.fn(), + }, + }, +})); + +describe('Tasks window', () => { + const rmfApi = new MockRmfApi(); + rmfApi.tasksApi.queryTaskStatesTasksGet = vi.fn().mockResolvedValue({ data: [] }); + + const Base = (props: React.PropsWithChildren<{}>) => { + return ( + + {props.children} + + ); + }; + + it('renders without crashing', () => { + const root = render( + + + , + ); + expect(root.getByText('Tasks')).toBeTruthy(); + }); + + it('triggers task refresh when Refresh button is clicked', () => { + render( {}} />); + const refreshButton = screen.getByTestId('refresh-button'); + act(() => { + fireEvent.click(refreshButton); + }); + expect(AppEvents.refreshTaskApp.next).toHaveBeenCalled(); + }); +}); diff --git a/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.tsx b/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.tsx index bd697f144..5f18e609a 100644 --- a/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.tsx +++ b/packages/rmf-dashboard-framework/src/components/tasks/tasks-window.tsx @@ -33,7 +33,7 @@ import { exportCsvFull, exportCsvMinimal } from './utils'; const RefreshTaskQueueTableInterval = 15000; const QueryLimit = 100; -enum TaskTablePanel { +export enum TaskTablePanel { QueueTable = 0, Schedule = 1, } @@ -182,35 +182,43 @@ export const TasksWindow = React.memo( labelFilter = `${filterColumn.substring(6)}=${filterValue}`; } - const resp = await rmfApi.tasksApi.queryTaskStatesTasksGet( - filterColumn && filterColumn === 'id_' ? filterValue : undefined, - filterColumn && filterColumn === 'category' ? filterValue : undefined, - filterColumn && filterColumn === 'requester' ? filterValue : undefined, - filterColumn && filterColumn === 'assigned_to' ? filterValue : undefined, - filterColumn && filterColumn === 'status' ? filterValue : undefined, - labelFilter, - filterColumn && filterColumn === 'unix_millis_request_time' ? filterValue : undefined, - filterColumn && filterColumn === 'unix_millis_start_time' ? filterValue : undefined, - filterColumn && filterColumn === 'unix_millis_finish_time' ? filterValue : undefined, - GET_LIMIT, - (tasksState.page - 1) * GET_LIMIT, // Datagrid component need to start in page 1. Otherwise works wrong - orderBy, - undefined, - ); - const results = resp.data as TaskState[]; - const newTasks = results.slice(0, GET_LIMIT); + try { + const resp = await rmfApi.tasksApi.queryTaskStatesTasksGet( + filterColumn && filterColumn === 'id_' ? filterValue : undefined, + filterColumn && filterColumn === 'category' ? filterValue : undefined, + filterColumn && filterColumn === 'requester' ? filterValue : undefined, + filterColumn && filterColumn === 'assigned_to' ? filterValue : undefined, + filterColumn && filterColumn === 'status' ? filterValue : undefined, + labelFilter, + filterColumn && filterColumn === 'unix_millis_request_time' ? filterValue : undefined, + filterColumn && filterColumn === 'unix_millis_start_time' ? filterValue : undefined, + filterColumn && filterColumn === 'unix_millis_finish_time' ? filterValue : undefined, + GET_LIMIT, + (tasksState.page - 1) * GET_LIMIT, // Datagrid component need to start in page 1. Otherwise works wrong + orderBy, + undefined, + ); + const results = resp.data as TaskState[]; + const newTasks = results.slice(0, GET_LIMIT); - setTasksState((old) => ({ - ...old, - isLoading: false, - data: newTasks, - total: - results.length === GET_LIMIT - ? tasksState.page * GET_LIMIT + 1 - : tasksState.page * GET_LIMIT - 9, - })); + setTasksState((old) => ({ + ...old, + isLoading: false, + data: newTasks, + total: + results.length === GET_LIMIT + ? tasksState.page * GET_LIMIT + 1 + : tasksState.page * GET_LIMIT - 9, + })); + } catch (e) { + appController.showAlert( + 'error', + `Failed to query task states: ${(e as Error).message}`, + ); + } })(); }, [ + appController, rmfApi, refreshTaskAppCount, tasksState.page, @@ -340,6 +348,7 @@ export const TasksWindow = React.memo(