replace TextField type date with DatePicker/DateTimePicker, reset page when typing in the search input (RankingPage), change useDebouncedCallback options (RankingPage)

This commit is contained in:
Dawid Wysokiński 2020-12-29 21:00:09 +01:00
parent 3a93de8792
commit dab5f698e5
16 changed files with 82 additions and 72 deletions

View File

@ -7,15 +7,19 @@ import {
import useI18N from './useI18N';
import useDialogStyles from './useDialogStyles';
function DatePicker({ className, ...props }: DatePickerProps) {
function DatePicker({
className,
format = 'yyyy/MM/dd',
...props
}: DatePickerProps) {
const classes = useDialogStyles();
const translations = useI18N();
return (
<MUIDatePicker
{...props}
format={format}
DialogProps={{ className: clsx(className, classes.dialog) }}
okLabel={translations.okLabel}
cancelLabel={translations.cancelLabel}
{...translations}
/>
);
}

View File

@ -10,6 +10,7 @@ import useDialogStyles from './useDialogStyles';
function DateTimePicker({
className,
ampm = false,
format = 'yyyy/MM/dd HH:mm',
...props
}: DateTimePickerProps) {
const classes = useDialogStyles();
@ -18,9 +19,9 @@ function DateTimePicker({
<MUIDateTimePicker
{...props}
ampm={ampm}
format={format}
DialogProps={{ className: clsx(className, classes.dialog) }}
okLabel={translations.okLabel}
cancelLabel={translations.cancelLabel}
{...translations}
/>
);
}

View File

@ -4,6 +4,7 @@ import { DATE_PICKER } from '@config/namespaces';
type Translations = {
cancelLabel: string;
okLabel: string;
todayLabel: string;
};
const useI18N = (): Translations => {
@ -12,6 +13,7 @@ const useI18N = (): Translations => {
return {
cancelLabel: t('cancelLabel'),
okLabel: t('okLabel'),
todayLabel: t('todayLabel'),
};
};

View File

@ -1,11 +1,10 @@
import React from 'react';
import { format, isValid } from 'date-fns';
import React, { useRef } from 'react';
import { useQuery } from '@apollo/client';
import {
useQueryParams,
NumberParam,
withDefault,
DateParam,
DateTimeParam,
} from 'use-query-params';
import useScrollToElement from '@libs/useScrollToElement';
import { validateRowsPerPage } from '@common/Table/helpers';
@ -13,8 +12,8 @@ import { ENNOBLEMENTS } from './queries';
import { LIMIT } from './constants';
import { makeStyles } from '@material-ui/core/styles';
import { TextField } from '@material-ui/core';
import TableToolbar from '@common/Table/TableToolbar';
import DateTimePicker from '@common/Picker/DateTimePicker';
import Table from '../Table/Table';
import { TFunction } from 'i18next';
@ -28,11 +27,12 @@ export interface Props {
function LatestSavedEnnoblements({ t, server }: Props) {
const classes = useStyles();
const now = useRef(new Date());
const [query, setQuery] = useQueryParams({
page: withDefault(NumberParam, 0),
limit: withDefault(NumberParam, LIMIT),
ennobledAtGTE: withDefault(DateParam, undefined),
ennobledAtLTE: withDefault(DateParam, undefined),
ennobledAtGTE: withDefault(DateTimeParam, new Date(0)),
ennobledAtLTE: withDefault(DateTimeParam, now.current),
});
const limit = validateRowsPerPage(query.limit);
useScrollToElement(document.documentElement, [query.page, limit]);
@ -60,23 +60,30 @@ function LatestSavedEnnoblements({ t, server }: Props) {
<div>
<TableToolbar className={classes.tableToolbar}>
{[
{ id: 'ennobledAtGTE', defaultValue: query.ennobledAtGTE },
{ id: 'ennobledAtLTE', defaultValue: query.ennobledAtLTE },
].map(({ id, defaultValue }) => {
{
id: 'ennobledAtGTE',
value: query.ennobledAtGTE,
maxDate: query.ennobledAtLTE,
},
{
id: 'ennobledAtLTE',
value: query.ennobledAtLTE,
minDate: query.ennobledAtGTE,
},
].map(({ id, value, maxDate, minDate }) => {
return (
<TextField
type="date"
<DateTimePicker
size="small"
key={id}
label={t('latestSavedEnnoblements.inputs.' + id)}
defaultValue={
defaultValue && defaultValue instanceof Date
? format(defaultValue, 'yyyy-MM-dd')
: undefined
}
onChange={e => {
const date = new Date(e.target.value);
setQuery({ [id]: isValid(date) ? date : undefined });
value={value}
disableFuture
variant="dialog"
maxDate={maxDate}
minDate={minDate}
showTodayButton
onChange={d => {
setQuery({ [id]: d ? d : undefined, page: 0 });
}}
InputLabelProps={{
shrink: true,

View File

@ -34,8 +34,9 @@ function Ranking({ server, t }: Props) {
});
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);

View File

@ -1,5 +1,4 @@
import React, { useState } from 'react';
import { format, isValid } from 'date-fns';
import {
useQueryParams,
NumberParam,
@ -17,10 +16,11 @@ import { validateRowsPerPage } from '@common/Table/helpers';
import { COLUMNS, LIMIT, DEFAULT_SORT } from './constants';
import { makeStyles } from '@material-ui/core/styles';
import { Paper, TextField } from '@material-ui/core';
import { Paper } from '@material-ui/core';
import Table from '@common/Table/Table';
import TableToolbar from '@common/Table/TableToolbar';
import SearchInput from '@common/Form/SearchInput';
import DatePicker from '@common/Picker/DatePicker';
import PlayerProfileLink from '@features/ServerPage/common/PlayerProfileLink/PlayerProfileLink';
import { TFunction } from 'i18next';
@ -44,8 +44,9 @@ function Ranking({ t }: Props) {
const limit = validateRowsPerPage(query.limit);
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);
@ -63,18 +64,14 @@ function Ranking({ t }: Props) {
return (
<Paper>
<TableToolbar className={classes.tableToolbar}>
<TextField
type="date"
<DatePicker
size="small"
label={t('ranking.createDateInputLabel')}
defaultValue={
query.createDate && query.createDate instanceof Date
? format(query.createDate, 'yyyy-MM-dd')
: undefined
}
onChange={e => {
const date = new Date(e.target.value);
setQuery({ createDate: isValid(date) ? date : undefined });
value={query.createDate}
disableFuture
variant="dialog"
onChange={d => {
setQuery({ createDate: d ? d : undefined, page: 0 });
}}
InputLabelProps={{
shrink: true,

View File

@ -34,8 +34,9 @@ function Ranking({ server, t }: Props) {
});
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);

View File

@ -37,8 +37,9 @@ function Ranking({ server, t }: Props) {
const limit = validateRowsPerPage(query.limit);
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useScrollToElement(document.documentElement, [query.page, limit]);
useUpdateEffect(() => {

View File

@ -41,4 +41,4 @@ export const COLUMNS: Column<Player>[] = [
export const LIMIT = 25;
export const DEFAULT_SORT = decodeSort('scoreAtt DESC');
export const DEFAULT_SORT = decodeSort('scoreTotal DESC');

View File

@ -35,8 +35,9 @@ function Ranking({ server, t }: Props) {
});
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);

View File

@ -1,5 +1,4 @@
import React, { useState } from 'react';
import { format, isValid } from 'date-fns';
import {
useQueryParams,
NumberParam,
@ -18,10 +17,11 @@ import * as ROUTES from '@config/routes';
import { COLUMNS, LIMIT, DEFAULT_SORT } from './constants';
import { makeStyles } from '@material-ui/core/styles';
import { Paper, TextField } from '@material-ui/core';
import { Paper } from '@material-ui/core';
import Table from '@common/Table/Table';
import TableToolbar from '@common/Table/TableToolbar';
import SearchInput from '@common/Form/SearchInput';
import DatePicker from '@common/Picker/DatePicker';
import Link from '@common/Link/Link';
import { TFunction } from 'i18next';
@ -45,8 +45,9 @@ function Ranking({ t }: Props) {
const limit = validateRowsPerPage(query.limit);
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);
@ -64,18 +65,14 @@ function Ranking({ t }: Props) {
return (
<Paper>
<TableToolbar className={classes.tableToolbar}>
<TextField
type="date"
<DatePicker
size="small"
label={t('ranking.createDateInputLabel')}
defaultValue={
query.createDate && query.createDate instanceof Date
? format(query.createDate, 'yyyy-MM-dd')
: undefined
}
onChange={e => {
const date = new Date(e.target.value);
setQuery({ createDate: isValid(date) ? date : undefined });
value={query.createDate}
disableFuture
variant="dialog"
onChange={d => {
setQuery({ createDate: d ? d : undefined, page: 0 });
}}
InputLabelProps={{
shrink: true,

View File

@ -35,8 +35,9 @@ function Ranking({ server, t }: Props) {
});
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);

View File

@ -38,8 +38,9 @@ function Ranking({ server, t }: Props) {
const limit = validateRowsPerPage(query.limit);
const [q, setQ] = useState(query.q);
const debouncedSetQuery = useDebouncedCallback(
value => setQuery({ q: value }),
1000
value => setQuery({ q: value, page: 0 }),
500,
{ maxWait: 1000 }
);
useUpdateEffect(() => {
debouncedSetQuery.callback(q);

View File

@ -34,4 +34,4 @@ export const COLUMNS: Column<Tribe>[] = [
export const LIMIT = 25;
export const DEFAULT_SORT = decodeSort('scoreAtt DESC');
export const DEFAULT_SORT = decodeSort('scoreTotal DESC');

View File

@ -7,6 +7,7 @@ import {
const createClient = (uri: string): ApolloClient<NormalizedCacheObject> => {
return new ApolloClient({
uri: uri,
queryDeduplication: true,
cache: new InMemoryCache({
typePolicies: {
FoundPlayer: {

View File

@ -19,6 +19,7 @@ const createTheme = (): Theme => {
props: {
MuiTextField: {
variant: 'outlined',
color: 'secondary',
},
MuiAppBar: {
color: 'default',
@ -27,12 +28,6 @@ const createTheme = (): Theme => {
color: 'secondary',
underline: 'none',
},
MuiInput: {
color: 'secondary',
},
MuiInputLabel: {
color: 'secondary',
},
},
overrides: {
MuiTab: {