Verified Commit c145bc79 authored by Marek Veselý's avatar Marek Veselý
Browse files

fix: stay on the same page when switching teams in instructor

parent cd8ab7d7
Loading
Loading
Loading
Loading
+30 −32
Original line number Diff line number Diff line
import type { TeamState } from '@inject/graphql'
import type { AnchorButtonProps } from '@blueprintjs/core'
import { LinkButton } from '@inject/shared'
import type { NavigateOptions } from '@tanstack/react-router'
import { useMatches } from '@tanstack/react-router'
import { type FC } from 'react'
import { TeamLabel } from '../../components/TeamLabel'
import { InstructorTeamLayoutRoute } from '../../routes/_protected/instructor/$exerciseId/$teamId/route'

interface TeamButtonProps {
  teamState: TeamState
  hideLabel: boolean | undefined
  exerciseId: string
  teamId: string
  buttonProps: AnchorButtonProps
}

const TeamButton: FC<TeamButtonProps> = ({ teamState, hideLabel }) => (
export const TeamButton: FC<TeamButtonProps> = ({
  exerciseId,
  teamId,
  buttonProps,
}) => {
  const matches = useMatches()
  const { params, fullPath } = matches.at(-1) ?? {}
  const teamSelected = !!params && 'teamId' in params && !!params.teamId

  return (
    <LinkButton
    key={teamState.id}
    link={{
      to: InstructorTeamLayoutRoute.to,
      link={
        {
          to: teamSelected ? fullPath : InstructorTeamLayoutRoute.to,
          params: {
        exerciseId: teamState.exercise.id,
        teamId: teamState.id,
            ...(teamSelected ? params : {}),
            exerciseId,
            teamId,
          },
    }}
    button={{
      alignText: 'left',
      fill: true,
      minimal: true,
      title: teamState.name,
      children: (
        <TeamLabel
          teamState={teamState}
          hideLabel={hideLabel}
          minimal
          showUsers
        />
      ),
      ellipsizeText: true,
    }}
        } as NavigateOptions
      }
      button={buttonProps}
    />
  )

export default TeamButton
}
+19 −3
Original line number Diff line number Diff line
import type { FC } from 'react'
import TeamButton from './TeamButton'
import { TeamLabel } from '../../components'
import { TeamButton } from './TeamButton'
import { useSubscribedTeams } from './useSubscribedTeams'

const TeamListVertical: FC<{
@@ -16,8 +17,23 @@ const TeamListVertical: FC<{
      {selectedTeamStates.map(teamState => (
        <TeamButton
          key={teamState.id}
          hideLabel={hideLabel}
          exerciseId={teamState.exercise.id}
          teamId={teamState.id}
          buttonProps={{
            alignText: 'left',
            fill: true,
            minimal: true,
            title: teamState.name,
            children: (
              <TeamLabel
                teamState={teamState}
                hideLabel={hideLabel}
                minimal
                showUsers
              />
            ),
            ellipsizeText: true,
          }}
        />
      ))}
    </>
+22 −28
Original line number Diff line number Diff line
import type { AnchorButtonProps } from '@blueprintjs/core'
import {
  Boundary,
  Button,
@@ -8,12 +9,11 @@ import {
} from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import type { Team, TeamState } from '@inject/graphql'
import { LinkButton } from '@inject/shared'
import { useClickAway } from 'ahooks'
import type { FC } from 'react'
import { memo, useRef, useState } from 'react'
import { TeamButton } from '../../instructor/InstructorTeamSelector/TeamButton'
import { useSubscribedTeams } from '../../instructor/InstructorTeamSelector/useSubscribedTeams'
import { InstructorTeamLayoutRoute } from '../../routes/_protected/instructor/$exerciseId/$teamId/route'
import { barClass } from './barClass'

const buttonGroupContainer = css`
@@ -55,30 +55,6 @@ const Dropdown: FC<{
  )
}

const TeamButton: FC<{ item: Team; exerciseId: string }> = ({
  exerciseId,
  item,
}) => (
  <LinkButton
    key={item.id}
    link={{
      to: InstructorTeamLayoutRoute.to,
      params: {
        teamId: item.id,
        exerciseId,
      },
    }}
    button={{
      text: item.name,
      minimal: true,
      style: {
        minWidth: 'fit-content',
      },
    }}
  />
)

// TODO: when clicking (when no team is selected), loops and the tab becomes unresponsive
const TeamTabs: FC<{
  teamId?: string
  exerciseId: string
@@ -88,13 +64,26 @@ const TeamTabs: FC<{
    context: 'instructor',
  })

  const getButtonProps = (item: Team): AnchorButtonProps => ({
    text: item.name,
    minimal: true,
    style: {
      minWidth: 'fit-content',
    },
  })

  const overflowRenderer = (overflowItems: Team[]) => (
    <div style={{ marginLeft: 'auto' }}>
      <Popover
        content={
          <ButtonGroup vertical className={buttonGroupContainer}>
            {overflowItems.map(item => (
              <TeamButton key={item.id} exerciseId={exerciseId} item={item} />
              <TeamButton
                key={item.id}
                exerciseId={exerciseId}
                teamId={item.id}
                buttonProps={getButtonProps(item)}
              />
            ))}
          </ButtonGroup>
        }
@@ -106,7 +95,12 @@ const TeamTabs: FC<{
  )

  const visibleItemRenderer = (item: Team) => (
    <TeamButton exerciseId={exerciseId} item={item} />
    <TeamButton
      key={item.id}
      exerciseId={exerciseId}
      teamId={item.id}
      buttonProps={getButtonProps(item)}
    />
  )

  return (