Filter on groups in teams table (#321)

This commit is contained in:
Erik Vroon
2023-11-08 16:23:32 +01:00
committed by GitHub
parent 28fd9dc61d
commit 8cf2dd4bba
4 changed files with 105 additions and 13 deletions

View File

@@ -33,6 +33,7 @@ export default function TeamModal({
onClick={() => setOpened(true)}
leftIcon={<GoPlus size={24} />}
title={operation_text}
style={{ marginTop: '1rem' }}
/>
</Group>
) : (

View File

@@ -16,11 +16,12 @@ import TableLayout, { ThNotSortable, ThSortable, getTableState, sortTableEntries
export default function TeamsTable({
tournamentData,
swrTeamsResponse,
teams,
}: {
tournamentData: TournamentMinimal;
swrTeamsResponse: SWRResponse;
teams: TeamInterface[];
}) {
const teams: TeamInterface[] = swrTeamsResponse.data != null ? swrTeamsResponse.data.data : [];
const tableState = getTableState('name');
if (swrTeamsResponse.error) return <RequestErrorAlert error={swrTeamsResponse.error} />;
@@ -39,6 +40,7 @@ export default function TeamsTable({
<td>
<DateTime datetime={team.created} />
</td>
<td>{team.swiss_score}</td>
<td>
<TeamModal
tournament_id={tournamentData.id}
@@ -72,6 +74,9 @@ export default function TeamsTable({
<ThSortable state={tableState} field="created">
Created
</ThSortable>
<ThSortable state={tableState} field="swiss_score">
Swiss score
</ThSortable>
<ThNotSortable>{null}</ThNotSortable>
</tr>
</thead>

View File

@@ -1,30 +1,93 @@
import { Grid, Title } from '@mantine/core';
import { Grid, Group, Select, Title } from '@mantine/core';
import React, { useState } from 'react';
import { SWRResponse } from 'swr';
import TeamModal from '../../../components/modals/team_modal';
import TeamsTable from '../../../components/tables/teams';
import { getTournamentIdFromRouter } from '../../../components/utils/util';
import { getTeams } from '../../../services/adapter';
import { getTournamentIdFromRouter, responseIsValid } from '../../../components/utils/util';
import { StageItemWithRounds } from '../../../interfaces/stage_item';
import { StageItemInput } from '../../../interfaces/stage_item_input';
import { TeamInterface } from '../../../interfaces/team';
import { getStages, getTeams } from '../../../services/adapter';
import { getStageItemList, getStageItemTeamIdsLookup } from '../../../services/lookups';
import TournamentLayout from '../_tournament_layout';
function StageItemSelect({
groupStageItems,
setFilteredStageItemId,
}: {
groupStageItems: any;
setFilteredStageItemId: any;
}) {
if (groupStageItems == null) return null;
const data = groupStageItems.map(([stage_item]: [StageItemWithRounds]) => ({
value: `${stage_item.id}`,
label: `${stage_item.name}`,
}));
return (
<Select
data={data}
label="Filter group stages"
placeholder="No filter"
dropdownPosition="bottom"
clearable
searchable
limit={25}
onChange={(x) => {
setFilteredStageItemId(x);
}}
/>
);
}
export default function Teams() {
const [filteredStageItemId, setFilteredStageItemId] = useState(null);
const { tournamentData } = getTournamentIdFromRouter();
const swrTeamsResponse: SWRResponse = getTeams(tournamentData.id);
const swrStagesResponse = getStages(tournamentData.id);
const stageItemInputLookup = responseIsValid(swrStagesResponse)
? getStageItemList(swrStagesResponse)
: [];
const stageItemTeamLookup = responseIsValid(swrStagesResponse)
? getStageItemTeamIdsLookup(swrStagesResponse)
: {};
const groupStageItems = Object.values(stageItemInputLookup).filter(
([stageItem]: [StageItemWithRounds]) => stageItem.type === 'ROUND_ROBIN'
);
let teams: TeamInterface[] = swrTeamsResponse.data != null ? swrTeamsResponse.data.data : [];
if (filteredStageItemId != null) {
teams = swrTeamsResponse.data.data.filter(
(team: StageItemInput) => stageItemTeamLookup[filteredStageItemId].indexOf(team.id) !== -1
);
}
return (
<TournamentLayout tournament_id={tournamentData.id}>
<Grid grow>
<Grid.Col span={9}>
<Grid grow mb="0.5rem">
<Grid.Col span={6}>
<Title>Teams</Title>
</Grid.Col>
<Grid.Col span={3}>
<TeamModal
swrTeamsResponse={swrTeamsResponse}
tournament_id={tournamentData.id}
team={null}
/>
<Grid.Col span={6}>
<Group position="right">
<StageItemSelect
groupStageItems={groupStageItems}
setFilteredStageItemId={setFilteredStageItemId}
/>
<TeamModal
swrTeamsResponse={swrTeamsResponse}
tournament_id={tournamentData.id}
team={null}
/>
</Group>
</Grid.Col>
</Grid>
<TeamsTable swrTeamsResponse={swrTeamsResponse} tournamentData={tournamentData} />
<TeamsTable
swrTeamsResponse={swrTeamsResponse}
tournamentData={tournamentData}
teams={teams}
/>
</TournamentLayout>
);
}

View File

@@ -30,6 +30,29 @@ export function getStageItemLookup(swrStagesResponse: SWRResponse) {
return Object.fromEntries(result);
}
export function getStageItemList(swrStagesResponse: SWRResponse) {
let result: any[] = [];
swrStagesResponse.data.data.map((stage: StageWithStageItems) =>
stage.stage_items.forEach((stage_item) => {
result = result.concat([[stage_item]]);
})
);
return result;
}
export function getStageItemTeamIdsLookup(swrStagesResponse: SWRResponse) {
let result: any[] = [];
swrStagesResponse.data.data.map((stage: StageWithStageItems) =>
stage.stage_items.forEach((stageItem) => {
const teamIds = stageItem.inputs.map((input) => input.team_id);
result = result.concat([[stageItem.id, teamIds]]);
})
);
return Object.fromEntries(result);
}
export function getMatchLookup(swrStagesResponse: SWRResponse) {
let result: any[] = [];