Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PORTALS-3308 - What's in Portals Component (GoalsV2) #1399

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
6d2ccdb
Replace the Goals component with a copy, GoalsV2
afwillia Nov 14, 2024
6714f25
Update copies of Goals.Desktop, Goals.Mobile and index.ts for GoalsV2
afwillia Nov 14, 2024
3ba91fc
Copy Goals CSS as GoalsV2
afwillia Nov 14, 2024
50668f9
Add a box surrounding the GoalsV2Desktop panels
afwillia Nov 14, 2024
ca758c0
rearrange individual goal panels to match design
afwillia Nov 14, 2024
513fd94
Tweak styling of individual goal panels
afwillia Nov 14, 2024
0c25ce9
Format the box containing the goal cards
afwillia Nov 15, 2024
f2b888c
Turn each item into a Card
afwillia Nov 20, 2024
643f34b
Format the new box that contains the card links
afwillia Nov 20, 2024
f292993
add GoalsV2.stories.tsx
afwillia Nov 20, 2024
c68fb26
copy storybook from Goals
afwillia Nov 20, 2024
c845ed6
use the elite portal in the goalsV2 story
afwillia Nov 20, 2024
dfc72d9
merge main updates with react router v6
afwillia Nov 20, 2024
5eed0da
Add a unit test file for the individual cards
afwillia Nov 21, 2024
a089d30
Add unit tests for the GoalsV2 box
afwillia Nov 21, 2024
75c5cd0
Remove unnecessary mock access token from test
afwillia Nov 22, 2024
001f516
Merge branch 'main' into PORTALS-3308
afwillia Nov 22, 2024
7073b49
Merge branch 'main' into PORTALS-3308
afwillia Dec 2, 2024
3cc4331
Merge branch 'main' into PORTALS-3308
afwillia Dec 3, 2024
d795916
WIP: address Nick's comments in GoalsV2.
afwillia Dec 4, 2024
33e2dea
update goalsV2 tests
afwillia Dec 4, 2024
f68b999
change main box to Goals class instead of GoalsV2
afwillia Dec 4, 2024
20c7954
Move the GoalsV2DataProps into an array outside of the return statement
afwillia Dec 4, 2024
39b26c8
add space between header and button and round its corners.
afwillia Dec 5, 2024
a2e5844
Make the button link a prop
afwillia Dec 5, 2024
71c3d30
update tests with dataLink
afwillia Dec 5, 2024
430e34a
Add dataLink to stories
afwillia Dec 5, 2024
bef55b6
remove the goalsV2 scss file and just use MUI
afwillia Dec 5, 2024
abd1401
remove _goalsV2 from _all.scss
afwillia Dec 6, 2024
1c66e00
remove index.ts for GoalsV2
afwillia Jan 3, 2025
b06b062
Remove mobile goals V2 scss classes
afwillia Jan 3, 2025
a92b3eb
use the SRC mock server for testing
afwillia Jan 3, 2025
d9af147
remove commented-out test
afwillia Jan 3, 2025
83767b5
Merge branch 'PORTALS-3308' of https://github.com/afwillia/synapse-we…
afwillia Jan 3, 2025
b5dce74
remove link component from button
afwillia Jan 3, 2025
ce91962
small styling revisions
afwillia Jan 3, 2025
c0014f4
remove Link from imports
afwillia Jan 3, 2025
b32d893
Merge branch 'main' into PORTALS-3308
afwillia Jan 3, 2025
3c17042
remove GoalsV2 export from index.ts
afwillia Jan 3, 2025
c6ff7d4
remove React import
afwillia Jan 3, 2025
09e35ef
Merge branch 'main' into PORTALS-3308
afwillia Jan 3, 2025
78234d6
use Array.map instead of forEach to create each goals V2 card
afwillia Jan 6, 2025
e5066bd
use primary.main theme color for button
afwillia Jan 6, 2025
14c4f0f
remove ELITE-specific styling
afwillia Jan 6, 2025
65600c4
Create a hook that returns the download URL of assets from the goals …
afwillia Jan 14, 2025
a9ab48d
Add a unit test for useGetGoalData
afwillia Jan 14, 2025
38f31fd
Add useGetGoalData hook to goalsV2
afwillia Jan 14, 2025
be3acab
Add useGetGoalData hook to goals component
afwillia Jan 14, 2025
8322272
Merge branch 'main' into PORTALS-3308
afwillia Jan 14, 2025
f8d9bb0
Fix how useGetGoalData hook is used to get asset cards to render
afwillia Jan 16, 2025
241a3d0
Fix how useGetGoalData is used so the goals cards render
afwillia Jan 16, 2025
3f507a4
Use upload-artifact v4 as v3 is now deprecated
afwillia Jan 16, 2025
c3b98f8
Revert attempt to update upload-artifact action
afwillia Jan 16, 2025
0f04c4d
clean up Goals.tsx
afwillia Jan 16, 2025
e2efb0f
clean up GoalsV2.tsx
afwillia Jan 16, 2025
f510d93
mock getQueryTableResults in goalsV2.test
afwillia Jan 16, 2025
ca5858a
Use renderHook from testing-library/react
afwillia Jan 16, 2025
c14a305
Remove unnecessary log
afwillia Jan 16, 2025
b7eaf71
Apply suggestion to simplify crazy co-pilot code
afwillia Jan 16, 2025
02486ab
use userEvent.click instead of fireEvent.click
afwillia Jan 16, 2025
002f260
remove synapseError from import
afwillia Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import GoalsV2Desktop from './GoalsV2.Desktop'

const mockProps = {
asset: 'https://example.com/asset.jpg',
link: 'https://example.com',
countSql: 'SELECT COUNT(*) FROM syn12345',
title: 'Test Title',
summary: 'Test Summary',
}

const queryClient = new QueryClient()

describe('GoalsV2Desktop', () => {
test('renders the component with the correct props', () => {
render(
<QueryClientProvider client={queryClient}>
<GoalsV2Desktop {...mockProps} />
</QueryClientProvider>,
)

const image = screen.getByRole('img')
expect(image).toHaveAttribute('src', mockProps.asset)
expect(image).toHaveAttribute('alt', mockProps.title)

const title = screen.getByText(mockProps.title)
expect(title).toBeInTheDocument()
})

test('opens the link when the card is clicked', () => {
window.open = jest.fn()

render(
<QueryClientProvider client={queryClient}>
<GoalsV2Desktop {...mockProps} />
</QueryClientProvider>,
)

const card = screen.getByRole('button', { name: /Test Title/i })
fireEvent.click(card)
afwillia marked this conversation as resolved.
Show resolved Hide resolved

expect(window.open).toHaveBeenCalledWith(mockProps.link)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react'
import { GoalsV2DataProps } from './GoalsV2'
import QueryCount from '../QueryCount/QueryCount'
import IconButton from '@mui/material/IconButton'
import NavigateNextIcon from '@mui/icons-material/NavigateNext'
import { Typography } from '@mui/material'
import { Card, CardActionArea, CardContent, CardMedia } from '@mui/material'

export default function GoalsV2Desktop({
asset,
link,
countSql,
title,
}: GoalsV2DataProps) {
return (
<Card
sx={{
width: 200,
height: 'auto',
backgroundColor: 'transparent',
borderColor: 'transparent',
boxShadow: 'none',
}}
>
<CardActionArea onClick={() => window.open(link)}>
<CardMedia
component="img"
sx={{ height: 150, width: '100%', paddingX: 2, overflow: 'visible' }}
image={asset}
alt={title}
/>
<CardContent
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Typography variant="h6" component="strong" sx={{ marginRight: 1 }}>
{countSql && (
<QueryCount parens={false} query={{ sql: countSql }} />
)}
</Typography>
<Typography variant="body1">{title}</Typography>
<IconButton sx={{ color: '#5BA998' }}>
afwillia marked this conversation as resolved.
Show resolved Hide resolved
<NavigateNextIcon />
</IconButton>
</CardContent>
</CardActionArea>
</Card>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { GoalsV2DataProps } from './GoalsV2'
import ExpandableContent from '../home_page/ExpandableContent'
import QueryCount from '../QueryCount/QueryCount'
import { Button } from '@mui/material'

export default function GoalsV2Mobile({
link,
summary,
countSql,
title,
}: GoalsV2DataProps) {
const titleElement = (
<div className="GoalsV2__Mobile__Header">
afwillia marked this conversation as resolved.
Show resolved Hide resolved
{countSql && (
<span className="GoalsV2__Mobile__Header__Count">
<QueryCount parens={false} query={{ sql: countSql }} />
</span>
)}
<span className="GoalsV2__Mobile__Header__Title"> {title} </span>
</div>
)
const content = (
<div className="GoalsV2__Mobile__Content">
<p>{summary}</p>
<Button
variant="contained"
color="secondary"
className="GoalsV2__Mobile__Content__Link"
href={link}
>
Explore
</Button>
</div>
)
return <ExpandableContent title={titleElement} content={content} />
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Meta, StoryObj } from '@storybook/react'
import Goals from './GoalsV2'

const meta = {
title: 'Home Page/GoalsV2',
component: Goals,
parameters: {
chromatic: { viewports: [600, 1200] },
},
} satisfies Meta
export default meta
type Story = StoryObj<typeof meta>

export const Demo: Story = {
args: {
entityId: 'syn22315959',
},
}
114 changes: 114 additions & 0 deletions packages/synapse-react-client/src/components/GoalsV2/GoalsV2.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React from 'react'
import { render, screen, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import GoalsV2 from './GoalsV2'
import {
SynapseContextProvider,
SynapseContextType,
} from '../../utils/context/SynapseContext'

const mockSynapseContext: Partial<SynapseContextType> = {
accessToken: 'mockAccessToken',
Fixed Show fixed Hide fixed
isInExperimentalMode: false,
utcTime: false,
withErrorBoundary: false,
downloadCartPageUrl: '/DownloadCart',
appId: undefined,
}

const queryClient = new QueryClient()

const server = setupServer(
afwillia marked this conversation as resolved.
Show resolved Hide resolved
rest.post(
afwillia marked this conversation as resolved.
Show resolved Hide resolved
'https://repo-prod.prod.sagebase.org/repo/v1/entity/:entityId/table/query/async/start',
(req, res, ctx) => {
return res(
ctx.json<{ token: string }>({
token: 'mockToken',
}),
)
},
),
rest.get(
'https://repo-prod.prod.sagebase.org/repo/v1/entity/:entityId/table/query/async/get/:token',
(req, res, ctx) => {
return res(
ctx.json({
queryResult: {
queryResults: {
rows: [
{
values: [
'syn22315959',
'SELECT COUNT(*) FROM syn22315959',
'Sample Title',
'Sample Summary',
'https://example.com',
'12345',
],
},
],
},
},
}),
)
},
),
)

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

describe('GoalsV2', () => {
test('renders the component with provided props', async () => {
render(
<QueryClientProvider client={queryClient}>
<SynapseContextProvider synapseContext={mockSynapseContext}>
<GoalsV2 entityId="syn22315959" />
</SynapseContextProvider>
</QueryClientProvider>,
)

await waitFor(() => {
expect(screen.getByText("What's in the Portal?")).toBeInTheDocument()
})
})

// test('displays error message on fetch failure', async () => {
afwillia marked this conversation as resolved.
Show resolved Hide resolved
// server.use(
// rest.get('https://repo-prod.prod.sagebase.org/repo/v1/entity/:entityId/table/query/async/get/:token', (req, res, ctx) => {
// return res(ctx.status(500), ctx.json({ message: 'Internal Server Error' }))
// })
// )

// render(
// <QueryClientProvider client={queryClient}>
// <SynapseContextProvider synapseContext={mockSynapseContext}>
// <GoalsV2 entityId="syn22315959" />
// </SynapseContextProvider>
// </QueryClientProvider>
// )

// await waitFor(() => {
// expect(screen.getByText('Error: Internal Server Error')).toBeInTheDocument()
// })
// })

test('displays assets when fetch is successful', async () => {
render(
<QueryClientProvider client={queryClient}>
<SynapseContextProvider synapseContext={mockSynapseContext}>
<GoalsV2 entityId="syn22315959" />
</SynapseContextProvider>
</QueryClientProvider>,
)

await waitFor(() => {
expect(screen.getByText("What's in the Portal?")).toBeInTheDocument()
})
})
})
Loading
Loading