Skip to content

Commit

Permalink
🐛 Fix TickersDropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
0x46616c6b committed Oct 24, 2023
1 parent a23a9fb commit f7f4bd5
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/api/User.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ApiUrl, Response } from './Api'
import { Ticker } from './Ticker'

export interface UsersResponseData {
users: Array<User>
Expand All @@ -14,7 +15,7 @@ export interface User {
email: string
role: string
isSuperAdmin: boolean
tickers?: Array<number>
tickers?: Array<Ticker>
}

export interface UserData {
Expand Down
53 changes: 53 additions & 0 deletions src/components/ticker/TickersDropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react'
import { fireEvent, render, screen } from '@testing-library/react'
import TickersDropdown from './TickersDropdown'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { Ticker } from '../../api/Ticker'

describe('TickersDropdown', () => {
beforeEach(() => {
fetchMock.resetMocks()
})

function setup(defaultValue: Array<Ticker>, onChange: (tickers: Array<Ticker>) => void) {
const client = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
})
return render(
<QueryClientProvider client={client}>
<TickersDropdown defaultValue={defaultValue} name="tickers" onChange={onChange} />
</QueryClientProvider>
)
}

it('should renders correctly', async () => {
const ticker = {
id: 1,
title: 'Ticker 1',
}
fetchMock.mockResponseOnce(
JSON.stringify({
data: {
tickers: [ticker],
},
status: 'success',
})
)
const handleChange = jest.fn()
setup([], handleChange)

fireEvent.mouseDown(screen.getByRole('button'))
const listbox = await screen.findByRole('listbox')
expect(listbox).toBeInTheDocument()
const option = await screen.findByRole('option')
expect(option).toBeInTheDocument()
fireEvent.click(option)
expect(handleChange).toHaveBeenCalledTimes(1)
expect(handleChange).toHaveBeenCalledWith([ticker])
expect(fetchMock).toHaveBeenCalledTimes(1)
})
})
47 changes: 30 additions & 17 deletions src/components/ticker/TickersDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@ import useAuth from '../useAuth'

interface Props {
name: string
defaultValue: Array<number>
onChange: (tickers: number[]) => void
defaultValue: Array<Ticker>
onChange: (tickers: Array<Ticker>) => void
sx?: SxProps
}

const TickersDropdown: FC<Props> = ({ name, defaultValue, onChange, sx }) => {
const [options, setOptions] = useState<Array<Ticker>>([])
const [tickers, setTickers] = useState<Array<number>>(defaultValue)
const [tickers, setTickers] = useState<Array<Ticker>>(defaultValue)
const { token } = useAuth()
const { getTickers } = useTickerApi(token)
const theme = useTheme()

const handleChange = (event: SelectChangeEvent<typeof tickers>) => {
if (typeof event.target.value !== 'string') {
setTickers(event.target.value)
onChange(event.target.value)
}
const handleChange = (event: SelectChangeEvent<number[]>) => {
const tickerIds = event.target.value as Array<number>
const selectedTickers = options.filter(ticker => {
return tickerIds.includes(ticker.id)
})
setTickers(selectedTickers)
onChange(selectedTickers)
}

useEffect(() => {
Expand All @@ -40,13 +42,13 @@ const TickersDropdown: FC<Props> = ({ name, defaultValue, onChange, sx }) => {

return (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{selectedTickers.map(ticker => (
{selectedTickers.map(selectedTicker => (
<Chip
key={ticker.id}
label={ticker.title}
key={selectedTicker.id}
label={selectedTicker.title}
onDelete={() => {
const reduced = tickers.filter(id => {
return id !== ticker.id
const reduced = tickers.filter(ticker => {
return selectedTicker.id !== ticker.id
})
setTickers(reduced)
onChange(reduced)
Expand All @@ -60,18 +62,29 @@ const TickersDropdown: FC<Props> = ({ name, defaultValue, onChange, sx }) => {
)
}

const getStyle = (value: number, tickers: number[]) => {
const getStyle = (value: Ticker, tickers: Array<Ticker>) => {
const tickerIds = tickers.map(ticker => ticker.id)
return {
fontWeight: tickers.indexOf(value) === -1 ? theme.typography.fontWeightRegular : theme.typography.fontWeightMedium,
fontWeight: tickerIds.indexOf(value.id) === -1 ? theme.typography.fontWeightRegular : theme.typography.fontWeightMedium,
}
}

const tickerIds = tickers.map(ticker => ticker.id)

return (
<FormControl sx={sx}>
<InputLabel>Tickers</InputLabel>
<Select input={<OutlinedInput label="Tickers" />} label="Tickers" multiple name={name} onChange={handleChange} renderValue={renderValue} value={tickers}>
<Select
input={<OutlinedInput label="Tickers" />}
label="Tickers"
multiple
name={name}
onChange={handleChange}
renderValue={renderValue}
value={tickerIds}
>
{options.map(ticker => (
<MenuItem key={ticker.id} selected={tickers.includes(ticker.id)} style={getStyle(ticker.id, tickers)} value={ticker.id}>
<MenuItem key={ticker.id} selected={tickers.includes(ticker)} style={getStyle(ticker, tickers)} value={ticker.id}>
{ticker.title}
</MenuItem>
))}
Expand Down
3 changes: 2 additions & 1 deletion src/components/user/UserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useQueryClient } from '@tanstack/react-query'
import useAuth from '../useAuth'
import { FormControlLabel, Checkbox, FormGroup, TextField, Typography, Grid, Divider } from '@mui/material'
import TickersDropdown from '../ticker/TickersDropdown'
import { Ticker } from '../../api/Ticker'

interface Props {
id: string
Expand All @@ -17,7 +18,7 @@ interface FormValues {
isSuperAdmin: boolean
password: string
password_validate: string
tickers: Array<number>
tickers: Array<Ticker>
}

const UserForm: FC<Props> = ({ id, user, callback }) => {
Expand Down

0 comments on commit f7f4bd5

Please sign in to comment.