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

VACMS-16290 Event Listing #322

Merged
merged 29 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e194438
wip
jtmst Jan 4, 2024
33802e0
Adds SSG as CLI option (#318)
ryguyk Jan 3, 2024
4583ed7
fix unused vars in code scan alerts (#319)
tjheffner Jan 3, 2024
3de79ea
Fix preview (#320)
tjheffner Jan 3, 2024
44d6454
build the preview server output as part of CI (#321)
tjheffner Jan 4, 2024
5e3f12a
Bump eslint-plugin-testing-library from 6.1.0 to 6.2.0 (#324)
dependabot[bot] Jan 8, 2024
f6e03a3
Bump @department-of-veterans-affairs/component-library from 31.0.0 to…
dependabot[bot] Jan 8, 2024
e9d3017
Bump @typescript-eslint/eslint-plugin from 6.14.0 to 6.18.0 (#326)
dependabot[bot] Jan 8, 2024
3d01e7b
Bump @department-of-veterans-affairs/formation from 7.1.0 to 10.1.0 (…
dependabot[bot] Jan 8, 2024
a9082de
update event listing mock & tests, generator message for mocking
tjheffner Jan 8, 2024
624b4a9
update snapshot
tjheffner Jan 8, 2024
7c76a74
event listing + query test, stub event calls
tjheffner Jan 9, 2024
22e9c16
fix test errors
tjheffner Jan 9, 2024
3c44955
event listing layout looks pretty close
tjheffner Jan 9, 2024
049f045
event listing has events on it
tjheffner Jan 9, 2024
69f58c3
update event listing so lovell menus render properly
tjheffner Jan 9, 2024
506c363
Merge branch 'main' into 16290-event-listings
tjheffner Jan 9, 2024
66fe4fa
clean up types a bit. events are a lovell resource too
tjheffner Jan 10, 2024
db3aeb5
dont change api-explorer yet
tjheffner Jan 10, 2024
53f3c68
update test, snapshot
tjheffner Jan 10, 2024
1337823
add guard for menu
tjheffner Jan 10, 2024
3cf296d
conditional menu render on template page
tjheffner Jan 10, 2024
250b8dd
fix logic checks
tjheffner Jan 10, 2024
22e69b3
Merge branch 'main' into 16290-event-listings
timcosgrove Jan 10, 2024
85bd049
Merge branch 'main' into 16290-event-listings
tjheffner Jan 11, 2024
2542d71
Merge branch 'main' into 16290-event-listings
tjheffner Jan 12, 2024
3034187
Merge branch 'main' into 16290-event-listings
tjheffner Jan 22, 2024
70b8e38
extra check for event listing
tjheffner Jan 22, 2024
1e0e994
Merge branch 'main' into 16290-event-listings
tjheffner Jan 22, 2024
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
21 changes: 21 additions & 0 deletions playwright/tests/eventListing.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { test, expect } = require('../utils/next-test')

test.describe('eventListing', () => {
test('eventListing page renders', async ({
page,
}) => {
await page.goto('/update-this-link')
await expect(page).toHaveURL('/update-this-link')
})

test('Should render without a11y errors', async ({
page,
makeAxeBuilder,
}) => {
await page.goto('/update-this-link')

const accessibilityScanResults = await makeAxeBuilder().analyze()

expect(accessibilityScanResults.violations).toEqual([])
})
})
51 changes: 51 additions & 0 deletions src/data/queries/eventListing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { QueryData, QueryFormatter, QueryParams } from 'next-drupal-query'
import { drupalClient } from '@/lib/drupal/drupalClient'
Fixed Show fixed Hide fixed
import { queries } from '.'
import { NodeEventListing } from '@/types/drupal/node'
import { EventListing } from '@/types/formatted/eventListing'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'
import { ExpandedStaticPropsContext } from '@/lib/drupal/staticProps'
import {
entityBaseFields,
fetchSingleEntityOrPreview,
} from '@/lib/drupal/query'

// Define the query params for fetching node--event_listing.
export const params: QueryParams<null> = () => {
return queries
.getParams()
// uncomment to add referenced entity data to the response
// .addInclude([
// 'field_media',
// 'field_media.image',
// 'field_administration',
// ])
}

// Define the option types for the data loader.
export type EventListingDataOpts = {
id: string
context?: ExpandedStaticPropsContext
}

// Implement the data loader.
export const data: QueryData<EventListingDataOpts, NodeEventListing> = async (
opts
): Promise<NodeEventListing> => {
const entity = (await fetchSingleEntityOrPreview(
opts,
RESOURCE_TYPES.EVENT_LISTING,
params
)) as NodeEventListing

console.log(entity)
return entity
}

export const formatter: QueryFormatter<NodeEventListing, EventListing> = (
entity: NodeEventListing
) => {
return {
...entityBaseFields(entity)
}
}
33 changes: 33 additions & 0 deletions src/data/queries/eventListingTeaser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { QueryData, QueryFormatter, QueryParams } from 'next-drupal-query'
Fixed Show fixed Hide fixed
import { drupalClient } from '@/lib/drupal/drupalClient'
Fixed Show fixed Hide fixed
import { queries } from '.'
import { NodeEventListingTeaser } from '@/types/drupal/node'

Check failure on line 4 in src/data/queries/eventListingTeaser.ts

View workflow job for this annotation

GitHub Actions / Setup and Test

'"@/types/drupal/node"' has no exported member named 'NodeEventListingTeaser'. Did you mean 'NodeEventListing'?
import { EventListingTeaser } from '@/types/formatted/eventListingTeaser'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'
Fixed Show fixed Hide fixed
import { ExpandedStaticPropsContext } from '@/lib/drupal/staticProps'
Fixed Show fixed Hide fixed
import {
fetchSingleEntityOrPreview,
} from '@/lib/drupal/query'
Fixed Show fixed Hide fixed

// Define the query params for fetching node--event_listing_teaser.
export const params: QueryParams<null> = () => {
return queries
.getParams()
.addInclude(['field_media', 'field_media.image', 'field_listing'])
}

export const formatter: QueryFormatter<NodeEventListingTeaser, EventListingTeaser> = (
entity: NodeEventListingTeaser
) => {
return {
id: entity.id,
type: entity.type,
published: entity.status,
headingLevel: 'h2',
title: entity.title,
image: queries.formatData('media--image', entity.field_media),
link: entity.path.alias,
introText: entity.field_intro_text,
lastUpdated: entity.field_last_saved_by_an_editor || entity.created,
}
}
4 changes: 4 additions & 0 deletions src/data/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import * as StaticPathResources from './staticPathResources'
import * as HeaderFooter from './headerFooter'
import * as PromoBlock from './promoBlock'
import * as Event from './event'
import * as EventListing from './eventListing'
import * as EventListingTeaser from './eventListingTeaser'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'

export const QUERIES_MAP = {
Expand All @@ -27,6 +29,8 @@ export const QUERIES_MAP = {
'node--story_listing': StoryListing,
'node--q_a': QuestionAnswer,
'node--event': Event,
'node--event_listing': EventListing,
'node--event_listing--teaser': EventListingTeaser,
'node--person_profile': PersonProfile,
'node--landing_page': BenefitsHub, // "Benefits Hub Landing Page"
'paragraph--audience_topics': AudienceTopics,
Expand Down
25 changes: 25 additions & 0 deletions src/data/queries/tests/eventListing.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { EventListing } from '@/types/drupal/node'

Check failure on line 1 in src/data/queries/tests/eventListing.test.tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

'"@/types/drupal/node"' has no exported member named 'EventListing'. Did you mean 'NodeEventListing'?
import { queries } from '@/data/queries'
import mockData from '@/mocks/EventListing.mock.json'

Check failure on line 3 in src/data/queries/tests/eventListing.test.tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Cannot find module '@/mocks/EventListing.mock.json' or its corresponding type declarations.

const EventListingMock: EventListing = mockData

describe('EventListing formatData', () => {
let windowSpy

beforeEach(() => {
windowSpy = jest.spyOn(window, 'window', 'get')
})

afterEach(() => {
windowSpy.mockRestore()
})

test('outputs formatted data', () => {
windowSpy.mockImplementation(() => undefined)

expect(
queries.formatData('node--event_listing', EventListingMock)
).toMatchSnapshot()
})
})
25 changes: 25 additions & 0 deletions src/data/queries/tests/eventListingTeaser.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { EventListingTeaser } from '@/types/drupal/node'

Check failure on line 1 in src/data/queries/tests/eventListingTeaser.test.tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Module '"@/types/drupal/node"' has no exported member 'EventListingTeaser'.
import { queries } from '@/data/queries'
import mockData from '@/mocks/EventListingTeaser.mock.json'

Check failure on line 3 in src/data/queries/tests/eventListingTeaser.test.tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Cannot find module '@/mocks/EventListingTeaser.mock.json' or its corresponding type declarations.

const EventListingTeaserMock: EventListingTeaser = mockData

describe('EventListingTeaser formatData', () => {
let windowSpy

beforeEach(() => {
windowSpy = jest.spyOn(window, 'window', 'get')
})

afterEach(() => {
windowSpy.mockRestore()
})

test('outputs formatted data', () => {
windowSpy.mockImplementation(() => undefined)

expect(
queries.formatData('node--event_listing_teaser', EventListingTeaserMock)

Check failure on line 22 in src/data/queries/tests/eventListingTeaser.test.tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Argument of type '"node--event_listing_teaser"' is not assignable to parameter of type 'NonNullable<"media--image" | "node--event" | "node--news_story" | "node--person_profile" | "node--q_a" | "node--story_listing" | "paragraph--audience_topics" | "paragraph--button" | ... 13 more ... | "header-footer-data">'.
).toMatchSnapshot()
})
})
1 change: 1 addition & 0 deletions src/lib/constants/resourceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const RESOURCE_TYPES = {
STORY_LISTING: 'node--story_listing',
STORY: 'node--news_story',
EVENT: 'node--event',
EVENT_LISTING: 'node--event_listing'
// QA: 'node--q_a',
} as const

Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function filterInvalidCrumbs(
}

export const shouldHideHomeBreadcrumb = (resourceType) => {
const typesToShowHomeBreadcrumb = [RESOURCE_TYPES.EVENT]
const typesToShowHomeBreadcrumb = [RESOURCE_TYPES.EVENT, RESOURCE_TYPES.EVENT_LISTING]

return !typesToShowHomeBreadcrumb.includes(resourceType)
}
4 changes: 4 additions & 0 deletions src/mocks/eventListing.mock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"note": "Replace this data! The file should contain an example response for the desired query before formatting",
"example": "See src/mocks/newsStory.mock.json for an example response from va.gov-cms's JSON:API"
}
4 changes: 4 additions & 0 deletions src/mocks/eventListingTeaser.mock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"note": "Replace this data! The file should contain an example response for the desired query before formatting",
"example": "See src/mocks/newsStory.mock.json for an example response from va.gov-cms's JSON:API"
}
6 changes: 6 additions & 0 deletions src/pages/[[...slug]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import HTMLComment from '@/templates/globals/util/HTMLComment'
import { shouldHideHomeBreadcrumb } from '@/lib/utils/breadcrumbs'
import { Event } from '@/templates/layouts/event'
import { EventListing } from '@/templates/layouts/eventListing'
import { getStaticPathsByResourceType } from '@/lib/drupal/staticPaths'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'
import {
Expand All @@ -24,6 +25,7 @@
import { LayoutProps } from '@/templates/globals/wrapper'
import { NewsStory as FormattedNewsStory } from '@/types/formatted/newsStory'
import { StoryListing as FormattedStoryListing } from '@/types/formatted/storyListing'
import { EventListing as FormattedEventListing } from '@/types/formatted/eventListing'
import { Event as FormattedEvent } from '@/types/formatted/event'
import { Meta } from '@/templates/globals/meta'
import { PreviewCrumb } from '@/templates/common/preview'
Expand All @@ -32,6 +34,7 @@
RESOURCE_TYPES.STORY_LISTING,
RESOURCE_TYPES.STORY,
RESOURCE_TYPES.EVENT,
RESOURCE_TYPES.EVENT_LISTING,
] as const

export type BuiltResourceType = (typeof RESOURCE_TYPES_TO_BUILD)[number]
Expand All @@ -51,8 +54,8 @@
if (!resource) return null
const comment = `
--
| resourceType: ${resource?.type || 'N/A'}

Check failure on line 57 in src/pages/[[...slug]].tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Property 'type' does not exist on type 'StaticPropsResource<FormattedResource>'.
| path: ${resource?.entityPath || 'N/A'}

Check failure on line 58 in src/pages/[[...slug]].tsx

View workflow job for this annotation

GitHub Actions / Setup and Test

Property 'entityPath' does not exist on type 'StaticPropsResource<FormattedResource>'.
| entityId: ${resource?.entityId || 'N/A'}
|
`
Expand Down Expand Up @@ -85,6 +88,9 @@
{/* {resource.type === RESOURCE_TYPES.QA && (
<QuestionAnswer {...resource} />
)} */}
{resource.type === RESOURCE_TYPES.EVENT_LISTING && (
<EventListing {...(resource as FormattedEventListing)} />
)}
{resource.type === RESOURCE_TYPES.EVENT && (
<Event {...(resource as FormattedEvent)} />
)}
Expand Down
17 changes: 17 additions & 0 deletions src/templates/layouts/eventListing/eventListing.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Meta, StoryObj } from '@storybook/react'

import { EventListing } from './index'

const meta: Meta<typeof EventListing> = {
title: 'Uncategorized/EventListing',
component: EventListing,
}
export default meta

type Story = StoryObj<typeof EventListing>

export const Example: Story = {
args: {
title: 'Hello World!'
},
}
11 changes: 11 additions & 0 deletions src/templates/layouts/eventListing/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { render, screen } from '@testing-library/react'
import { EventListing } from './index'


describe('EventListing with valid data', () => {
test('renders EventListing component', () => {
render(<EventListing title={'Hello world'} />)

expect(screen.queryByText(/Hello world/)).toBeInTheDocument()
})
})
47 changes: 47 additions & 0 deletions src/templates/layouts/eventListing/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffect } from "react";
Fixed Show fixed Hide fixed

type EventListingProps = {
title: string
}

export function EventListing({ title, fieldIntroText, entityUrl, facilitySidebar, reverseFieldListingNode, pastEvents }: EventListingProps) {
// useEffect(() => {
// window.allEventTeasers = reverseFieldListingNode;
// window.pastEvents = pastEvents;
// }, [reverseFieldListingNode, pastEvents]);
return (
<div>
<h1>EVENT LISTING</h1>
<p>{title}</p>
</div>

// <div className="interior vads-u-padding-bottom--3" id="content">
// <main className="va-l-detail-page va-facility-page">
// <div className="usa-grid usa-grid-full">
// <div className="events vads-u-display--flex vads-u-flex-direction--column vads-u-padding-x--1p5 medium-screen:vads-u-padding-x--0 vads-u-padding-bottom--2">
// <h1 id="article-heading">{title}</h1>
// <div className="va-introtext">
// {fieldIntroText && (
// <p className="events-show" id="office-events-description">
// {fieldIntroText}
// </p>
// )}
// </div>
// </div>
// <div data-widget-type="events"></div>
// </div>
// </main>
// <div className="usa-grid usa-grid-full">
// <div className="last-updated vads-u-padding-x--1 large-screen:vads-u-padding-x--0">
// <div className="vads-u-display--flex above-footer-elements-container">
// <div className="vads-u-flex--1 vads-u-text-align--right">
// <span className="vads-u-text-align--right">

// </span>
// </div>
// </div>
// </div>
// </div>
// </div>
)
}
2 changes: 2 additions & 0 deletions src/types/drupal/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export type NodeTypes =
| NodeSupportResourcesDetailPage
| NodeSupportService
| NodeEvent
| NodeEventListing

/** Node resource types. */
export const enum NodeResourceType {
Expand All @@ -68,6 +69,7 @@ export const enum NodeResourceType {
PromoBanner = 'node--promo_banner',
QuestionAnswer = 'node--q_a',
StoryListing = 'node--story_listing',
EventListing = 'node--event_lising',
SupportResourcesDetailPage = 'node--support_resources_detail_page',
}

Expand Down
3 changes: 3 additions & 0 deletions src/types/formatted/eventListing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type EventListing = {
title: string
}
3 changes: 3 additions & 0 deletions src/types/formatted/eventListingTeaser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type EventListingTeaser = {
title: string
}
Loading