Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
shini4i committed May 27, 2024
1 parent be10b50 commit baf71b6
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 55 deletions.
12 changes: 12 additions & 0 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/react": "^18.3.3",
"@types/react-datepicker": "^6.2.0",
"@types/react-dom": "^18.3.0",
"jest": "^29.7.0"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';

function ApplicationsFilter({ value, onChange, appNames }) {
const [applications, setApplications] = useState([]);
interface ApplicationsFilterProps {
value: string | null;
onChange: (newValue: string | null) => void;
appNames: string[];
}

const ApplicationsFilter: React.FC<ApplicationsFilterProps> = ({ value, onChange, appNames }) => {
const [applications, setApplications] = useState<string[]>([]);

useEffect(() => {
setApplications(appNames);
}, [appNames]);

const handleApplicationsChange = (_event, newValue) => {
onChange?.(newValue);
const handleApplicationsChange = (_event: React.ChangeEvent<{}>, newValue: string | null) => {
if (onChange) {
onChange(newValue);
}
};

return (
<Autocomplete
size={'small'}
size="small"
disablePortal
options={applications}
sx={{ width: 220 }}
Expand All @@ -25,12 +32,6 @@ function ApplicationsFilter({ value, onChange, appNames }) {
onChange={handleApplicationsChange}
/>
);
}

ApplicationsFilter.propTypes = {
value: PropTypes.any,
onChange: PropTypes.func,
appNames: PropTypes.array.isRequired
};

export default ApplicationsFilter;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { forwardRef, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useSearchParams } from 'react-router-dom';
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';
Expand All @@ -16,45 +15,48 @@ import ApplicationsFilter from './ApplicationsFilter';
import TasksTable, { useTasks } from './TasksTable';
import { useErrorContext } from '../ErrorContext';

const DateRangePickerCustomInput = forwardRef(({ value, onClick }, ref) => (
<TextField
size="small"
sx={{ minWidth: '220px' }}
onClick={onClick}
ref={ref}
value={value}
label="Date range"
/>
));
interface DateRangePickerCustomInputProps {
value: string;
onClick: () => void;
}

DateRangePickerCustomInput.propTypes = {
value: PropTypes.string,
onClick: PropTypes.func.isRequired,
};
const DateRangePickerCustomInput = forwardRef<HTMLInputElement, DateRangePickerCustomInputProps>(
({ value, onClick }, ref) => (
<TextField
size="small"
sx={{ minWidth: '220px' }}
onClick={onClick}
ref={ref}
value={value}
label="Date range"
InputProps={{ readOnly: true }}
/>
)
);

DateRangePickerCustomInput.displayName = 'DateRangePickerCustomInput';

function HistoryTasks() {
interface HistoryTasksProps {}

const HistoryTasks: React.FC<HistoryTasksProps> = () => {
const [searchParams, setSearchParams] = useSearchParams();
const { setError, setSuccess } = useErrorContext();
const { tasks, sortField, setSortField, appNames, refreshTasksInRange, clearTasks } =
useTasks({ setError, setSuccess });
const [currentApplication, setCurrentApplication] = useState(
searchParams.get('app') ?? null,
const [currentApplication, setCurrentApplication] = useState<string | null>(
searchParams.get('app')
);
const [dateRange, setDateRange] = useState([
Number(searchParams.get('start'))
? new Date(Number(searchParams.get('start')) * 1000)
: startOfDay(new Date()),
Number(searchParams.get('end'))
? new Date(Number(searchParams.get('end')) * 1000)
: startOfDay(new Date()),
const [dateRange, setDateRange] = useState<[Date | null, Date | null]>([
searchParams.get('start') ? new Date(Number(searchParams.get('start')) * 1000) : startOfDay(new Date()),
searchParams.get('end') ? new Date(Number(searchParams.get('end')) * 1000) : startOfDay(new Date()),
]);
const [startDate, endDate] = dateRange;
const [currentPage, setCurrentPage] = useState(
searchParams.get('page') ? Number(searchParams.get('page')) : 1,
const [currentPage, setCurrentPage] = useState<number>(
searchParams.get('page') ? Number(searchParams.get('page')) : 1
);

const updateSearchParameters = (start, end, application, page) => {
const params = {
const updateSearchParameters = (start: Date, end: Date, application: string | null, page: number) => {
const params: Record<string, any> = {
start: Math.floor(start.getTime() / 1000),
end: Math.floor(end.getTime() / 1000),
};
Expand All @@ -70,12 +72,12 @@ function HistoryTasks() {
setSearchParams(params);
};

const refreshWithFilters = (start, end, application, page) => {
const refreshWithFilters = (start: Date | null, end: Date | null, application: string | null, page: number) => {
if (start && end) {
refreshTasksInRange(
Math.floor(startOfDay(start).getTime() / 1000),
Math.floor(endOfDay(end).getTime() / 1000),
application,
application
);
updateSearchParameters(start, end, application, page);
} else {
Expand All @@ -84,7 +86,7 @@ function HistoryTasks() {
};

useEffect(() => {
refreshWithFilters(startDate, endDate, currentApplication, currentPage);
refreshWithFilters(startDate!, endDate!, currentApplication, currentPage);
}, [startDate, endDate, currentApplication, currentPage]);

return (
Expand Down Expand Up @@ -117,26 +119,29 @@ function HistoryTasks() {
onChange={value => {
setCurrentApplication(value);
setCurrentPage(1);
refreshWithFilters(startDate, endDate, value, 1);
refreshWithFilters(startDate!, endDate!, value, 1);
}}
setError={setError}
setSuccess={setSuccess}
appNames={appNames}
/>
</Box>
<Box>
<DatePicker
selectsRange={true}
selectsRange
startDate={startDate}
endDate={endDate}
onChange={update => {
onChange={(update: [Date | null, Date | null]) => {
setDateRange(update);
setCurrentPage(1);
refreshWithFilters(update[0], update[1], currentApplication, 1);
}}
maxDate={new Date()}
isClearable={false}
customInput={<DateRangePickerCustomInput />}
customInput={
<DateRangePickerCustomInput
value={`${startDate ? startDate.toLocaleDateString() : ''} - ${endDate ? endDate.toLocaleDateString() : ''}`}
onClick={() => {}}
/>
}
required
/>
</Box>
Expand All @@ -147,7 +152,7 @@ function HistoryTasks() {
title="Reload table"
onClick={() => {
setCurrentPage(1);
refreshWithFilters(startDate, endDate, currentApplication, 1);
refreshWithFilters(startDate!, endDate!, currentApplication, 1);
}}
>
<RefreshIcon />
Expand All @@ -165,16 +170,16 @@ function HistoryTasks() {
onPageChange={page => {
setCurrentPage(page);
updateSearchParameters(
startDate,
endDate,
startDate!,
endDate!,
currentApplication,
page,
page
);
}}
/>
</Box>
</Container>
);
}
};

export default HistoryTasks;
82 changes: 82 additions & 0 deletions web/types/react-datepicker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
declare module 'react-datepicker' {
import * as React from 'react';
import { Locale } from 'date-fns';

interface ReactDatePickerProps {
selected?: Date | null;
onChange?: (date: Date | [Date | null, Date | null], event: React.SyntheticEvent<any> | undefined) => void;
onSelect?: (date: Date, event: React.SyntheticEvent<any> | undefined) => void;
onClickOutside?: (event: React.SyntheticEvent<any>) => void;
onChangeRaw?: (event: React.SyntheticEvent<any>) => void;
onFocus?: (event: React.SyntheticEvent<any>) => void;
onBlur?: (event: React.SyntheticEvent<any>) => void;
onKeyDown?: (event: React.SyntheticEvent<any>) => void;
dateFormat?: string | string[];
dateFormatCalendar?: string;
className?: string;
wrapperClassName?: string;
calendarClassName?: string;
todayButton?: React.ReactNode;
customInput?: React.ReactNode;
customInputRef?: string;
placeholderText?: string;
id?: string;
name?: string;
autoComplete?: string;
disabled?: boolean;
disabledKeyboardNavigation?: boolean;
open?: boolean;
openToDate?: Date;
minDate?: Date;
maxDate?: Date;
selectsStart?: boolean;
selectsEnd?: boolean;
startDate?: Date;
endDate?: Date;
excludeDates?: Date[];
filterDate?: (date: Date) => boolean;
fixedHeight?: boolean;
formatWeekNumber?: (date: Date) => string | number;
highlightDates?: Date[] | { [className: string]: Date[] };
includeDates?: Date[];
includeTimes?: Date[];
injectTimes?: Date[];
inline?: boolean;
locale?: string | Locale;
peekNextMonth?: boolean;
showMonthDropdown?: boolean;
showPreviousMonths?: boolean;
showYearDropdown?: boolean;
dropdownMode?: 'scroll' | 'select';
timeCaption?: string;
timeFormat?: string;
timeIntervals?: number;
minTime?: Date;
maxTime?: Date;
excludeTimes?: Date[];
useWeekdaysShort?: boolean;
showTimeSelect?: boolean;
showTimeSelectOnly?: boolean;
utcOffset?: number;
weekLabel?: string;
withPortal?: boolean;
showWeekNumbers?: boolean;
forceShowMonthNavigation?: boolean;
showDisabledMonthNavigation?: boolean;
scrollableYearDropdown?: boolean;
scrollableMonthYearDropdown?: boolean;
yearDropdownItemNumber?: number;
previousMonthButtonLabel?: React.ReactNode;
nextMonthButtonLabel?: React.ReactNode;
previousYearButtonLabel?: string;
nextYearButtonLabel?: string;
timeInputLabel?: string;
inlineFocusSelectedMonth?: boolean;
shouldCloseOnSelect?: boolean;
useShortMonthInDropdown?: boolean;
}

class ReactDatePicker extends React.Component<ReactDatePickerProps, any> {}

export default ReactDatePicker;
}

0 comments on commit baf71b6

Please sign in to comment.