Refactored GetPlayers graphql query to pass where clause as variable (#946)

This commit is contained in:
Alec LaLonde
2021-12-03 09:41:51 -07:00
committed by GitHub
parent 1d74d7beea
commit 5f60d4a2f5
6 changed files with 94 additions and 66 deletions

View File

@@ -1,6 +1,6 @@
import { Flex, Skeleton, Text, TimezoneOptions, VStack } from '@metafam/ds';
import { PlayerList } from 'components/Player/PlayerList';
import { GetPlayersQueryVariables } from 'graphql/autogen/types';
import { PlayersQueryVariables } from 'graphql/getPlayers';
import { usePlayerFilter } from 'lib/hooks/players';
import { useOnScreen } from 'lib/hooks/useOnScreen';
import React, { useEffect, useMemo, useRef, useState } from 'react';
@@ -8,11 +8,11 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
import { PlayersLoading } from './PlayersLoading';
const getAdjacentTimezoneQueryVariables = (
defaultQueryVariables: GetPlayersQueryVariables,
): GetPlayersQueryVariables => {
defaultQueryVariables: PlayersQueryVariables,
): PlayersQueryVariables => {
const timezoneValue = defaultQueryVariables.timezones?.[0];
const timezone = TimezoneOptions.find((t) => t.value === timezoneValue);
const adjascentTimezones = timezone
const adjacentTimezones = timezone
? TimezoneOptions.filter(
(t) =>
Math.abs(t.offset - timezone.offset) <= 4 &&
@@ -22,20 +22,20 @@ const getAdjacentTimezoneQueryVariables = (
return {
...defaultQueryVariables,
offset: 0,
timezones: adjascentTimezones,
timezones: adjacentTimezones,
};
};
type Props = {
queryVariables: GetPlayersQueryVariables;
queryVariables: PlayersQueryVariables;
showSeasonalXP?: boolean;
};
export const AdjascentTimezonePlayers: React.FC<Props> = ({
export const AdjacentTimezonePlayers: React.FC<Props> = ({
queryVariables,
showSeasonalXP,
}) => {
const [variables, setVariables] = useState<GetPlayersQueryVariables>(
const [variables, setVariables] = useState<PlayersQueryVariables>(
getAdjacentTimezoneQueryVariables(queryVariables),
);

View File

@@ -19,7 +19,7 @@ import {
} from '@metafam/ds';
import { DesktopFilters } from 'components/Player/Filter/DesktopFilters';
import { MobileFilters } from 'components/Player/Filter/MobileFilters';
import { GetPlayersQueryVariables } from 'graphql/autogen/types';
import { PlayersQueryVariables } from 'graphql/getPlayers';
import {
PlayerAggregates,
QueryVariableSetter,
@@ -43,7 +43,7 @@ type Props = {
fetching: boolean;
fetchingMore: boolean;
aggregates: PlayerAggregates;
queryVariables: GetPlayersQueryVariables;
queryVariables: PlayersQueryVariables;
setQueryVariable: QueryVariableSetter;
resetFilter: () => void;
totalCount: number;
@@ -118,7 +118,7 @@ export const PlayerFilter: React.FC<Props> = ({
useEffect(() => {
setQueryVariable(
'availability',
availability ? parseInt(availability.value, 10) : 0,
availability ? parseInt(availability.value, 10) : null,
);
}, [setQueryVariable, availability]);

View File

@@ -23,7 +23,7 @@ import { useUser } from 'lib/hooks';
import React, { useEffect, useState } from 'react';
import { FaClock, FaGlobe } from 'react-icons/fa';
import { getPlayerTimeZoneDisplay } from 'utils/dateHelpers';
import { getPlayerDescription } from 'utils/playerHelpers';
import { getPlayerDescription, getPlayerName } from 'utils/playerHelpers';
import { ProfileSection } from '../../ProfileSection';
import { PlayerContacts } from '../PlayerContacts';
@@ -60,7 +60,7 @@ export const PlayerHero: React.FC<Props> = ({ player, isOwnProfile }) => {
setAvailabilityHours(person.availability_hours || 0);
setPronouns(person.pronouns || '');
setPlayerName(person.username);
setPlayerName(getPlayerName(person));
}
}, [user, player, isOwnProfile]);

View File

@@ -10,7 +10,9 @@ import {
GetPlayersQueryVariables,
GetPlayerUsernamesQuery,
GetPlayerUsernamesQueryVariables,
Maybe,
Order_By,
Player_Bool_Exp,
PlayerFragmentFragment,
} from './autogen/types';
import { client as defaultClient } from './client';
@@ -19,45 +21,21 @@ import { PlayerFragment, PlayerSkillFragment } from './fragments';
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
gql`
query GetPlayers(
$orderBy: player_order_by!
$offset: Int
$limit: Int
$skillIds: [uuid!]
$playerTypeIds: [Int!]
$availability: Int
$timezones: [String!]
$search: String
$orderBy: player_order_by!
$where: player_bool_exp
$forLoginDisplay: Boolean! = false
) {
player(
order_by: [$orderBy]
offset: $offset
limit: $limit
where: {
availability_hours: { _gte: $availability }
timezone: { _in: $timezones }
type: { id: { _in: $playerTypeIds } }
skills: { Skill: { id: { _in: $skillIds } } }
_or: [
{ username: { _ilike: $search } }
{ ethereum_address: { _ilike: $search } }
]
}
where: $where
) {
...PlayerFragment
}
player_aggregate(
where: {
availability_hours: { _gte: $availability }
timezone: { _in: $timezones }
type: { id: { _in: $playerTypeIds } }
skills: { Skill: { id: { _in: $skillIds } } }
_or: [
{ username: { _ilike: $search } }
{ ethereum_address: { _ilike: $search } }
]
}
) {
player_aggregate(where: $where) {
aggregate {
count
}
@@ -68,19 +46,63 @@ gql`
export const PLAYER_LIMIT = 9;
export const defaultQueryVariables: GetPlayersQueryVariables = {
export const defaultQueryVariables: PlayersQueryVariables = {
offset: 0,
limit: PLAYER_LIMIT,
availability: 0,
skillIds: null,
playerTypeIds: null,
timezones: null,
search: '%%',
orderBy: {
season_xp: 'desc' as Order_By,
},
};
export type PlayersQueryVariables = {
search: string;
offset: number;
limit: number;
orderBy: {
season_xp?: Maybe<Order_By> | undefined;
};
availability?: number;
skillIds?: string[];
playerTypeIds?: number[];
timezones?: string[];
};
export const transformToGraphQlVariables = (
queryVariables: PlayersQueryVariables,
): GetPlayersQueryVariables => {
const graphqlWhereClause: Player_Bool_Exp = {
_or: [
{ username: { _ilike: queryVariables.search } },
{ ethereum_address: { _ilike: queryVariables.search } },
],
};
if (queryVariables.availability != null) {
graphqlWhereClause.availability_hours = {
_gte: queryVariables.availability,
};
}
if (queryVariables.timezones?.length) {
graphqlWhereClause.timezone = { _in: queryVariables.timezones };
}
if (queryVariables.playerTypeIds?.length) {
graphqlWhereClause.type = { id: { _in: queryVariables.playerTypeIds } };
}
if (queryVariables.skillIds?.length) {
graphqlWhereClause.skills = {
Skill: { id: { _in: queryVariables.skillIds } },
};
}
return {
orderBy: queryVariables.orderBy,
offset: queryVariables.offset,
limit: queryVariables.limit,
where: graphqlWhereClause,
};
};
export type PlayersResponse = {
error: Error | undefined;
count: number;
@@ -94,7 +116,7 @@ export const getPlayersWithCount = async (
const { data, error } = await client
.query<GetPlayersQuery, GetPlayersQueryVariables>(
GetPlayersDocument,
queryVariables,
transformToGraphQlVariables(queryVariables),
)
.toPromise();

View File

@@ -1,11 +1,15 @@
import {
GetPlayersQueryVariables,
Player_Order_By,
PlayerFragmentFragment,
useGetPlayerFiltersQuery,
useGetPlayersQuery,
} from 'graphql/autogen/types';
import { defaultQueryVariables, PLAYER_LIMIT } from 'graphql/getPlayers';
import {
defaultQueryVariables,
PLAYER_LIMIT,
PlayersQueryVariables,
transformToGraphQlVariables,
} from 'graphql/getPlayers';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { CategoryOption, parseSkills } from 'utils/skillHelpers';
@@ -26,7 +30,7 @@ interface PlayerFilter {
fetching: boolean;
fetchingMore: boolean;
aggregates: PlayerAggregates;
queryVariables: GetPlayersQueryVariables;
queryVariables: PlayersQueryVariables;
setQueryVariable: QueryVariableSetter;
error?: Error;
resetFilter: () => void;
@@ -47,8 +51,8 @@ const usePlayerAggregates = () => {
};
};
const useFilteredPlayers = (queryVariables: GetPlayersQueryVariables) => {
const [variables, setVariables] = useState<GetPlayersQueryVariables>(
const useFilteredPlayers = (queryVariables: PlayersQueryVariables) => {
const [variables, setVariables] = useState<PlayersQueryVariables>(
defaultQueryVariables,
);
@@ -57,7 +61,7 @@ const useFilteredPlayers = (queryVariables: GetPlayersQueryVariables) => {
}, [queryVariables]);
const [{ fetching, data, error }] = useGetPlayersQuery({
variables,
variables: transformToGraphQlVariables(variables),
});
const players = data?.player || [];
@@ -122,12 +126,11 @@ const getOrderByValue = (option: SortOption): Player_Order_By =>
}).output;
export const usePlayerFilter = (
defaultVariables: GetPlayersQueryVariables = defaultQueryVariables,
defaultVariables: PlayersQueryVariables = defaultQueryVariables,
): PlayerFilter => {
const [
queryVariables,
setQueryVariables,
] = useState<GetPlayersQueryVariables>(defaultVariables);
const [queryVariables, setQueryVariables] = useState<PlayersQueryVariables>(
defaultVariables,
);
const aggregates = usePlayerAggregates();
@@ -205,7 +208,7 @@ export const usePlayerFilter = (
};
export const useFiltersUsed = (
queryVariables: GetPlayersQueryVariables,
queryVariables: PlayersQueryVariables,
): boolean => {
const sortFilterUsed = useMemo(
() => !Object.keys(queryVariables.orderBy).includes('season_xp'),
@@ -219,7 +222,7 @@ export const useFiltersUsed = (
queryVariables.search,
]);
const availabilityFilterUsed = useMemo(
() => (queryVariables.availability as number) > 0,
() => queryVariables.availability != null,
[queryVariables.availability],
);
const skillIdsFilterUsed = useMemo(
@@ -253,7 +256,7 @@ export const useFiltersUsed = (
};
const usePaginatedPlayers = (
queryVariables: GetPlayersQueryVariables,
queryVariables: PlayersQueryVariables,
setQueryVariable: QueryVariableSetter,
) => {
const {

View File

@@ -1,14 +1,17 @@
import { Text, VStack } from '@metafam/ds';
import { PageContainer } from 'components/Container';
import { AdjascentTimezonePlayers } from 'components/Player/Filter/AdjascentTimezonePlayers';
import { AdjacentTimezonePlayers } from 'components/Player/Filter/AdjacentTimezonePlayers';
import { PlayerFilter } from 'components/Player/Filter/PlayerFilter';
import { PlayersLoading } from 'components/Player/Filter/PlayersLoading';
import { PlayersNotFound } from 'components/Player/Filter/PlayersNotFound';
import { PlayerList } from 'components/Player/PlayerList';
import { HeadComponent } from 'components/Seo';
import { GetPlayersQueryVariables } from 'graphql/autogen/types';
import { getSsrClient } from 'graphql/client';
import { getPlayerFilters, getPlayersWithCount } from 'graphql/getPlayers';
import {
getPlayerFilters,
getPlayersWithCount,
PlayersQueryVariables,
} from 'graphql/getPlayers';
import { usePlayerFilter } from 'lib/hooks/players';
import { useOnScreen } from 'lib/hooks/useOnScreen';
import { InferGetStaticPropsType } from 'next';
@@ -109,7 +112,7 @@ export default Players;
type MorePlayersProps = {
fetching: boolean;
totalCount: number;
queryVariables: GetPlayersQueryVariables;
queryVariables: PlayersQueryVariables;
showSeasonalXP?: boolean;
};
@@ -128,7 +131,7 @@ const MorePlayers = React.forwardRef<HTMLDivElement, MorePlayersProps>(
) : null}
{!fetching && totalCount === 0 ? <PlayersNotFound /> : null}
{!fetching && isTimezoneSelected ? (
<AdjascentTimezonePlayers
<AdjacentTimezonePlayers
queryVariables={queryVariables}
showSeasonalXP={showSeasonalXP}
/>