From d7bc7bf82a6d523a302180e9f90386a94c6701cc Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Thu, 16 Mar 2023 14:56:50 -0400 Subject: [PATCH 1/6] chore: image-with-caption in-progress update --- gatsby/generic-pages/content-blocks.ts | 47 +++++++++++++++++++ .../untypedAccess/getDateProperty.spec.ts | 23 +++++++++ gatsby/utils/untypedAccess/getDateProperty.ts | 9 ++++ 3 files changed, 79 insertions(+) create mode 100644 gatsby/utils/untypedAccess/getDateProperty.spec.ts create mode 100644 gatsby/utils/untypedAccess/getDateProperty.ts diff --git a/gatsby/generic-pages/content-blocks.ts b/gatsby/generic-pages/content-blocks.ts index f7ded6628..5e31cc8b1 100644 --- a/gatsby/generic-pages/content-blocks.ts +++ b/gatsby/generic-pages/content-blocks.ts @@ -1,5 +1,6 @@ import { CreateNodeArgs } from 'gatsby' import { getArrayProperty } from '../utils/untypedAccess/getArrayProperty' +import { getDateProperty } from '../utils/untypedAccess/getDateProperty' import { getStringProperty } from '../utils/untypedAccess/getStringProperty' import { BlockNodeInput } from '../../src/types/generic-page.d' @@ -8,6 +9,7 @@ export const schema = ` union DABlockTypes = DABlockTitle | DABlockText | + DABlockImage | DABlockYoutube | DABlockTimeline @@ -19,6 +21,19 @@ export const schema = ` text: String! } + type DABlockImage implements Node { + asset: String! + caption: String + attribution: String! + dateUploaded: Date + date: Date + altText: String! + tags: [String!]! + + alignmentPhoto: String + alignmentCaption: String + } + type DABlockYoutube implements Node { title: String embedUrl: String! @@ -75,6 +90,9 @@ export const deriveBlockNode: DeriveBlockFn = ( case 'block-text': return deriveTextBlockNode(block, parentId, createNodeArgs) + case 'block-image-with-caption': + return deriveImageBlockNode(block, parentId, createNodeArgs) + case 'block-youtube-embed': return deriveYoutubeBlockNode(block, parentId, createNodeArgs) @@ -135,6 +153,35 @@ export const deriveTextBlockNode: DeriveBlockFn = ( } } +export const deriveImageBlockNode: DeriveBlockFn = ( + block, + parentId, + { createNodeId, createContentDigest }, +) => { + const altText = getStringProperty(block, 'altText') + return { + asset: getStringProperty(block, 'asset'), + caption: getStringProperty(block, 'caption'), + attribution: getStringProperty(block, 'attribution'), + dateUploaded: getDateProperty(block, 'dateUploaded'), + date: getDateProperty(block, 'date'), + altText: altText, + tags: getArrayProperty(block, 'tags'), + + alignmentPhoto: getStringProperty(block, 'alignmentPhoto'), + alignmentCaption: getStringProperty(block, 'alignmentCaption'), + + // Gatsby Fields + id: createNodeId(`DABlockImage - ${altText}`), + parent: parentId, + children: [], + internal: { + type: 'DABlockImage', + contentDigest: createContentDigest(JSON.stringify(block)), + }, + } +} + export const deriveYoutubeBlockNode: DeriveBlockFn = ( block, parentId, diff --git a/gatsby/utils/untypedAccess/getDateProperty.spec.ts b/gatsby/utils/untypedAccess/getDateProperty.spec.ts new file mode 100644 index 000000000..28039d3ec --- /dev/null +++ b/gatsby/utils/untypedAccess/getDateProperty.spec.ts @@ -0,0 +1,23 @@ +import { getDateProperty } from './getDateProperty' + +describe('getNumberProperty()', () => { + it('should return a Date property if present', () => + expect(getDateProperty({ foo: new Date('2019-01-17') }, 'foo')).toEqual( + new Date('2019-01-17'), + )) + + it('should throw an error if the object is undefined', () => + expect(() => getDateProperty(undefined, 'foo')).toThrow( + `Received undefined when trying to access property 'foo'!`, + )) + + it('should throw an error if the property is undefined', () => + expect(() => getDateProperty({}, 'foo')).toThrow( + `Object '{}' has no property 'foo'!`, + )) + + it('should throw an error if the property is not a Date', () => + expect(() => getDateProperty({ foo: 'not a Date' }, 'foo')).toThrow( + `Property 'foo' on object '{\"foo\":\"not a Date\"}' does not match expected type!`, + )) +}) diff --git a/gatsby/utils/untypedAccess/getDateProperty.ts b/gatsby/utils/untypedAccess/getDateProperty.ts new file mode 100644 index 000000000..cf9eba958 --- /dev/null +++ b/gatsby/utils/untypedAccess/getDateProperty.ts @@ -0,0 +1,9 @@ +import { getProperty } from './getProperty' + +/** + * Helper function for untyped date access + */ +export const getDateProperty = ( + o: Record | undefined, + property: string, +): Date => getProperty((v) => v instanceof Date)(o, property) From b4e69e8359caea9d831405bddc7cc073ae05d3f6 Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Thu, 23 Mar 2023 19:19:18 +0000 Subject: [PATCH 2/6] fix: handle image dates better --- gatsby/generic-pages/content-blocks.ts | 2 +- gatsby/utils/untypedAccess/getDateProperty.spec.ts | 7 ++++++- gatsby/utils/untypedAccess/getDateProperty.ts | 13 ++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gatsby/generic-pages/content-blocks.ts b/gatsby/generic-pages/content-blocks.ts index 5e31cc8b1..ad1e802e0 100644 --- a/gatsby/generic-pages/content-blocks.ts +++ b/gatsby/generic-pages/content-blocks.ts @@ -164,7 +164,7 @@ export const deriveImageBlockNode: DeriveBlockFn = ( caption: getStringProperty(block, 'caption'), attribution: getStringProperty(block, 'attribution'), dateUploaded: getDateProperty(block, 'dateUploaded'), - date: getDateProperty(block, 'date'), + date: block?.date ? getDateProperty(block, 'date') : undefined, altText: altText, tags: getArrayProperty(block, 'tags'), diff --git a/gatsby/utils/untypedAccess/getDateProperty.spec.ts b/gatsby/utils/untypedAccess/getDateProperty.spec.ts index 28039d3ec..5c26283d0 100644 --- a/gatsby/utils/untypedAccess/getDateProperty.spec.ts +++ b/gatsby/utils/untypedAccess/getDateProperty.spec.ts @@ -1,6 +1,6 @@ import { getDateProperty } from './getDateProperty' -describe('getNumberProperty()', () => { +describe('getDateProperty()', () => { it('should return a Date property if present', () => expect(getDateProperty({ foo: new Date('2019-01-17') }, 'foo')).toEqual( new Date('2019-01-17'), @@ -20,4 +20,9 @@ describe('getNumberProperty()', () => { expect(() => getDateProperty({ foo: 'not a Date' }, 'foo')).toThrow( `Property 'foo' on object '{\"foo\":\"not a Date\"}' does not match expected type!`, )) + + it('should throw an error if the property is not a valid Date', () => + expect(() => getDateProperty({ foo: new Date('invalid') }, 'foo')).toThrow( + `Property 'foo' on object '{\"foo\":null}' is an invalid Date!`, + )) }) diff --git a/gatsby/utils/untypedAccess/getDateProperty.ts b/gatsby/utils/untypedAccess/getDateProperty.ts index cf9eba958..a37265ab3 100644 --- a/gatsby/utils/untypedAccess/getDateProperty.ts +++ b/gatsby/utils/untypedAccess/getDateProperty.ts @@ -6,4 +6,15 @@ import { getProperty } from './getProperty' export const getDateProperty = ( o: Record | undefined, property: string, -): Date => getProperty((v) => v instanceof Date)(o, property) +): Date => { + const date = getProperty((v) => v instanceof Date)(o, property) + if (isNaN(date.valueOf())) { + throw new Error( + `Property '${property}' on object '${JSON.stringify( + o, + )}' is an invalid Date!`, + ) + } else { + return date + } +} From 41d59c7844103a2f79e3f365f5464d644e51ccc5 Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Sat, 25 Mar 2023 15:22:27 -0400 Subject: [PATCH 3/6] fix: actually get images into Gatsby graphql --- gatsby/generic-pages/content-blocks.ts | 7 +--- gatsby/generic-pages/generic-pages.spec.ts | 9 ++++- .../untypedAccess/getDateProperty.spec.ts | 22 +++++++---- gatsby/utils/untypedAccess/getDateProperty.ts | 30 +++++++++++--- src/types/generic-page.d.ts | 22 ++++++++++- src/types/generic-page.test-helpers.ts | 39 +++++++++++++++++-- 6 files changed, 105 insertions(+), 24 deletions(-) diff --git a/gatsby/generic-pages/content-blocks.ts b/gatsby/generic-pages/content-blocks.ts index ad1e802e0..cf60ee2e8 100644 --- a/gatsby/generic-pages/content-blocks.ts +++ b/gatsby/generic-pages/content-blocks.ts @@ -91,6 +91,7 @@ export const deriveBlockNode: DeriveBlockFn = ( return deriveTextBlockNode(block, parentId, createNodeArgs) case 'block-image-with-caption': + console.log(deriveImageBlockNode(block, parentId, createNodeArgs)) return deriveImageBlockNode(block, parentId, createNodeArgs) case 'block-youtube-embed': @@ -99,12 +100,6 @@ export const deriveBlockNode: DeriveBlockFn = ( case 'block-timeline': return deriveTimelineBlockNode(block, parentId, createNodeArgs) - case 'block-image-with-caption': - reporter.warn( - `Dropping content block type="${blockType}", since it is not implemented yet.`, - ) - return null - default: reporter.warn(`Dropping unknown content block: type="${blockType}"`) return null diff --git a/gatsby/generic-pages/generic-pages.spec.ts b/gatsby/generic-pages/generic-pages.spec.ts index 7331084a5..baf38d7a8 100644 --- a/gatsby/generic-pages/generic-pages.spec.ts +++ b/gatsby/generic-pages/generic-pages.spec.ts @@ -18,7 +18,12 @@ describe('Processes Page Data', () => { it('processes each type of page, section, and content block correctly', () => { // build our input const sectionData = factory.getSectionGridData({ - contentBlocks: [factory.getBlockTitleData(), factory.getBlockTextData()], + contentBlocks: [ + factory.getBlockTitleData(), + factory.getBlockTextData(), + factory.getBlockImageData(), + factory.getBlockYoutubeData(), + ], }) const pageData = factory.getPageData({ @@ -30,6 +35,8 @@ describe('Processes Page Data', () => { blocks: [ factory.getBlockTitleNodeInput(), factory.getBlockTextNodeInput(), + factory.getBlockImageNodeInput(), + factory.getBlockYoutubeNodeInput(), ], }) diff --git a/gatsby/utils/untypedAccess/getDateProperty.spec.ts b/gatsby/utils/untypedAccess/getDateProperty.spec.ts index 5c26283d0..55b7f90f0 100644 --- a/gatsby/utils/untypedAccess/getDateProperty.spec.ts +++ b/gatsby/utils/untypedAccess/getDateProperty.spec.ts @@ -1,10 +1,14 @@ import { getDateProperty } from './getDateProperty' describe('getDateProperty()', () => { - it('should return a Date property if present', () => + it('should return a Date property if present', () => { expect(getDateProperty({ foo: new Date('2019-01-17') }, 'foo')).toEqual( new Date('2019-01-17'), - )) + ) + expect(getDateProperty({ foo: '2019-01-17' }, 'foo')).toEqual( + new Date('2019-01-17'), + ) + }) it('should throw an error if the object is undefined', () => expect(() => getDateProperty(undefined, 'foo')).toThrow( @@ -16,13 +20,17 @@ describe('getDateProperty()', () => { `Object '{}' has no property 'foo'!`, )) - it('should throw an error if the property is not a Date', () => - expect(() => getDateProperty({ foo: 'not a Date' }, 'foo')).toThrow( - `Property 'foo' on object '{\"foo\":\"not a Date\"}' does not match expected type!`, + it('should throw an error if the property is not a Date or a datestring', () => + expect(() => getDateProperty({ foo: [] }, 'foo')).toThrow( + `Property 'foo' on object '{\"foo\":[]}' does not match expected type!`, )) - it('should throw an error if the property is not a valid Date', () => + it('should throw an error if the property is not a valid Date or datestring', () => { expect(() => getDateProperty({ foo: new Date('invalid') }, 'foo')).toThrow( `Property 'foo' on object '{\"foo\":null}' is an invalid Date!`, - )) + ) + expect(() => getDateProperty({ foo: 'invalid' }, 'foo')).toThrow( + `Property 'foo' on object '{\"foo\":\"invalid\"}' is an invalid Date!`, + ) + }) }) diff --git a/gatsby/utils/untypedAccess/getDateProperty.ts b/gatsby/utils/untypedAccess/getDateProperty.ts index a37265ab3..e36bf1655 100644 --- a/gatsby/utils/untypedAccess/getDateProperty.ts +++ b/gatsby/utils/untypedAccess/getDateProperty.ts @@ -1,20 +1,38 @@ -import { getProperty } from './getProperty' - /** - * Helper function for untyped date access + * Helper function for untyped date access. + * Handles dates in string form. */ export const getDateProperty = ( o: Record | undefined, property: string, ): Date => { - const date = getProperty((v) => v instanceof Date)(o, property) + if (o === undefined) { + throw new Error( + `Received undefined when trying to access property '${property}'!`, + ) + } + if (!(property in o)) { + throw new Error( + `Object '${JSON.stringify(o)}' has no property '${property}'!`, + ) + } + + const v = o[property] + if (!(v instanceof Date) && !(typeof v === 'string')) { + throw new Error( + `Property '${property}' on object '${JSON.stringify( + o, + )}' does not match expected type!`, + ) + } + + const date = new Date(v) if (isNaN(date.valueOf())) { throw new Error( `Property '${property}' on object '${JSON.stringify( o, )}' is an invalid Date!`, ) - } else { - return date } + return date } diff --git a/src/types/generic-page.d.ts b/src/types/generic-page.d.ts index 0be455217..991058541 100644 --- a/src/types/generic-page.d.ts +++ b/src/types/generic-page.d.ts @@ -186,7 +186,27 @@ Block: Image ------------------------------------------------------------ Stub. */ -export interface BlockImage {} +export interface BlockImage { + /** + * relative path to media file + */ + asset: string + + caption?: string + + /** + * Photo attribution. Usually a person or org name. + */ + attribution: string + + dateUploaded?: Date + date?: Date + altText: string + tags: string[] + + alignmentPhoto?: 'Left' | 'Center' | 'Right' + alignmentCaption?: 'Left' | 'Center' | 'Right' +} export interface BlockImageNodeInput extends BlockImage, NodeInput {} export interface BlockImageNode extends BlockImage, Node {} diff --git a/src/types/generic-page.test-helpers.ts b/src/types/generic-page.test-helpers.ts index 62118a5aa..e527adc9f 100644 --- a/src/types/generic-page.test-helpers.ts +++ b/src/types/generic-page.test-helpers.ts @@ -334,7 +334,7 @@ export const getBlockYoutubeData = (props?: Record) => { ...props, - template: 'block-youtube', + template: 'block-youtube-embed', } } @@ -477,7 +477,18 @@ export const getBlockImageData = (props?: Record) => { return { ...props, - template: 'block-card', + asset: '', + caption: 'An Image Block', + attribution: 'Distribute Aid', + dateUploaded: new Date(2020, 9, 8), + date: new Date(2020, 9, 8), + altText: 'A Fake Image', + tags: ['a tag'], + + alignmentPhoto: 'Left', + alignmentCaption: 'Right', + + template: 'block-image-with-caption', } } @@ -487,6 +498,17 @@ export const getBlockImageNodeInput = (props?: Record) => { parent: 'parent-id', children: [], + asset: '', + caption: 'An Image Block', + attribution: 'Distribute Aid', + dateUploaded: new Date(2020, 9, 8), + date: new Date(2020, 9, 8), + altText: 'A Fake Image', + tags: ['a tag'], + + alignmentPhoto: 'Left', + alignmentCaption: 'Right', + ...props, internal: { @@ -504,13 +526,24 @@ export const getBlockImageNode = (props?: Record) => { parent: 'parent-id', children: [], + asset: '', + caption: 'An Image Block', + attribution: 'Distribute Aid', + dateUploaded: new Date(2020, 9, 8), + date: new Date(2020, 9, 8), + altText: 'A Fake Image', + tags: ['a tag'], + + alignmentPhoto: 'Left', + alignmentCaption: 'Right', + ...props, internal: { contentDigest: 'content digest', ...props?.internal, - type: 'DABlockTimeline', + type: 'DABlockImage', }, } as BlockImageNode } From d045fc761d56795f992c1f6dd6163cbc63f94a26 Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Sat, 25 Mar 2023 15:55:49 -0400 Subject: [PATCH 4/6] feat: get image block component to show up on generic pages. --- gatsby/generic-pages/content-blocks.ts | 1 - src/components/section/ContentBlock.spec.tsx | 53 +++++++++++-------- src/components/section/ContentBlock.tsx | 8 ++- .../section/blocks/BlockImage.spec.tsx | 12 +++++ src/components/section/blocks/BlockImage.tsx | 11 ++++ src/pages/{DAPageGeneric.slug}.tsx | 16 ++++++ 6 files changed, 76 insertions(+), 25 deletions(-) create mode 100644 src/components/section/blocks/BlockImage.spec.tsx create mode 100644 src/components/section/blocks/BlockImage.tsx diff --git a/gatsby/generic-pages/content-blocks.ts b/gatsby/generic-pages/content-blocks.ts index cf60ee2e8..181163d7e 100644 --- a/gatsby/generic-pages/content-blocks.ts +++ b/gatsby/generic-pages/content-blocks.ts @@ -91,7 +91,6 @@ export const deriveBlockNode: DeriveBlockFn = ( return deriveTextBlockNode(block, parentId, createNodeArgs) case 'block-image-with-caption': - console.log(deriveImageBlockNode(block, parentId, createNodeArgs)) return deriveImageBlockNode(block, parentId, createNodeArgs) case 'block-youtube-embed': diff --git a/src/components/section/ContentBlock.spec.tsx b/src/components/section/ContentBlock.spec.tsx index d72364b2f..7bcf1d00f 100644 --- a/src/components/section/ContentBlock.spec.tsx +++ b/src/components/section/ContentBlock.spec.tsx @@ -15,40 +15,43 @@ describe('Blocks', () => { factory.getBlockTitleNode({ text: 'My Title' }), factory.getBlockTextNode({ text: 'My text.' }), factory.getBlockYoutubeNode({ title: 'My video.' }), + factory.getBlockImageNode({ alt: 'My Alt' }), ] }) it('can render multiple blocks', () => { - const { getByText } = render() + const { getByText, getByAltText } = render() - const title = getByText('My Title') - expect(title).toBeTruthy() + const titleElem = getByText('My Title') + expect(titleElem).toBeTruthy() - const text = getByText('My text.') - expect(text).toBeTruthy() + const textElem = getByText('My text.') + expect(textElem).toBeTruthy() - const youTubeTitle = getByText('My video.') - expect(youTubeTitle).toBeTruthy() + const youTubeElem = getByText('My video.') + expect(youTubeElem).toBeTruthy() + + const imageElem = getByAltText('My Alt') + expect(imageElem).toBeTruthy() }) it('gracefully drops unimplemented block types', () => { blocks = blocks.concat([ factory.getBlockTimelineNode(), - factory.getBlockImageNode(), factory.getBlockCardNode(), ]) const { getByText, queryByText } = render() - const title = getByText('My Title') - expect(title).toBeTruthy() + const titleElem = getByText('My Title') + expect(titleElem).toBeTruthy() - const text = getByText('My text.') - expect(text).toBeTruthy() + const textElem = getByText('My text.') + expect(textElem).toBeTruthy() - const timelineEntry = queryByText('2020') - expect(timelineEntry).toBeFalsy() + const timelineEntryElem = queryByText('2020') + expect(timelineEntryElem).toBeFalsy() - // TODO: add tests asserting image & card are dropped + // TODO: add tests asserting card are dropped }) it('throws an error when a block has an unknown type', () => { @@ -73,28 +76,34 @@ describe('Block', () => { it('can render a title block', () => { const block = factory.getBlockTitleNode({ text: 'My Title' }) const { getByText } = render() - const title = getByText('My Title') - expect(title).toBeTruthy() + const titleElem = getByText('My Title') + expect(titleElem).toBeTruthy() }) it('can render a text block', () => { const block = factory.getBlockTextNode({ text: 'My text.' }) const { getByText } = render() - const text = getByText('My text.') - expect(text).toBeTruthy() + const textElem = getByText('My text.') + expect(textElem).toBeTruthy() }) it('can render a youtube block', () => { const block = factory.getBlockYoutubeNode({ title: 'My video.' }) const { getByText } = render() - const text = getByText('My video.') - expect(text).toBeTruthy() + const youtubeElem = getByText('My video.') + expect(youtubeElem).toBeTruthy() + }) + + it('can render an image block', () => { + const block = factory.getBlockImageNode({ alt: 'My Alt' }) + const { getByAltText } = render() + const imageElem = getByAltText('My Alt') + expect(imageElem).toBeTruthy() }) test.todo('can render a timeline block') test.todo('can render a links list block') test.todo('can render an updates list block') - test.todo('can render an image block') test.todo('can render a card block') it('throws an error when a block has an unknown type', () => { diff --git a/src/components/section/ContentBlock.tsx b/src/components/section/ContentBlock.tsx index 94d0c070e..23bbec53e 100644 --- a/src/components/section/ContentBlock.tsx +++ b/src/components/section/ContentBlock.tsx @@ -1,5 +1,6 @@ import { FC } from 'react' import { + BlockImage as BlockImageType, BlockLinksList as BlockLinksListType, BlockNode, BlockText as BlockTextType, @@ -7,6 +8,7 @@ import { BlockUpdatesList as BlockUpdatesListType, BlockYoutube as BlockYoutubeType, } from '../../types/generic-page.d' +import { BlockImage } from './blocks/BlockImage' import { BlockLinksList } from './blocks/BlockLinksList' import { BlockText } from './blocks/BlockText' import { BlockTitle } from './blocks/BlockTitle' @@ -60,12 +62,14 @@ export const Block: FC = ({ block, className }) => { return ( ) + case 'DABlockImage': + return ( + + ) // wishlist case 'DABlockTimeline': return null - case 'DABlockImage': - return null case 'DABlockCard': return null diff --git a/src/components/section/blocks/BlockImage.spec.tsx b/src/components/section/blocks/BlockImage.spec.tsx new file mode 100644 index 000000000..ba21d9ac0 --- /dev/null +++ b/src/components/section/blocks/BlockImage.spec.tsx @@ -0,0 +1,12 @@ +import { render } from '@testing-library/react' +import { factory } from '../../../types/generic-page.test-helpers' +import { BlockImage } from './BlockImage' + +describe('BlockImage', () => { + it('renders the image and related content', () => { + const block = factory.getBlockImageNode({ alt: 'My Alt' }) + const { getByAltText } = render() + const title = getByAltText('My Alt') + expect(title).toBeTruthy() + }) +}) diff --git a/src/components/section/blocks/BlockImage.tsx b/src/components/section/blocks/BlockImage.tsx new file mode 100644 index 000000000..23e1777d0 --- /dev/null +++ b/src/components/section/blocks/BlockImage.tsx @@ -0,0 +1,11 @@ +import { FC } from 'react' +import { BlockImage as BlockImageType } from '../../../types/generic-page.d' + +type BlockImageProps = { + block: BlockImageType + className?: string | undefined +} + +export const BlockImage: FC = ({ block, className }) => { + return
image
+} diff --git a/src/pages/{DAPageGeneric.slug}.tsx b/src/pages/{DAPageGeneric.slug}.tsx index d2b61641d..761e975d9 100644 --- a/src/pages/{DAPageGeneric.slug}.tsx +++ b/src/pages/{DAPageGeneric.slug}.tsx @@ -76,6 +76,22 @@ export const query = graphql` title embedUrl } + ... on DABlockImage { + internal { + type + } + + asset + caption + attribution + dateUploaded + date + altText + tags + + alignmentPhoto + alignmentCaption + } ... on DABlockTimeline { internal { type From 5f3ef08205c5d0d4b859d6a01fa0bad7fb4c5a82 Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Sat, 25 Mar 2023 18:16:12 -0400 Subject: [PATCH 5/6] feat: show image blocks on generic pages --- gatsby-node.ts | 3 ++- gatsby/generic-pages/content-blocks.ts | 15 +++++++++------ gatsby/generic-pages/resolvers.ts | 11 +++++++++++ src/components/section/blocks/BlockImage.tsx | 11 ++++++++++- src/pages/{DAPageGeneric.slug}.tsx | 11 +++++++++-- src/types/generic-page.d.ts | 12 ++++++++++-- src/types/generic-page.test-helpers.ts | 14 ++++++++++---- 7 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 gatsby/generic-pages/resolvers.ts diff --git a/gatsby-node.ts b/gatsby-node.ts index 1d5d7547c..12cc6656f 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -6,13 +6,13 @@ import { createFundraiserSchemaCustomization, createFundraisersFromMarkdown, } from './gatsby/fundraisers/transformers' +import { createBlockPhotoResolvers } from './gatsby/generic-pages/resolvers' import { sourceNeedsAssessments } from './gatsby/needs-assessment/sourceNeedsAssessmentData' import { createPhotoResolvers, createPhotoSchemaCustomization, } from './gatsby/photos/photos' import transformers from './gatsby/transform-nodes' - /* Customize the GraqphQL Schema ================================================================================ @@ -59,6 +59,7 @@ export const createResolvers: GatsbyNode['createResolvers'] = (args) => { resolvers.resolveSubregionFields(args) resolvers.resolveTeamMemberFields(args) createPhotoResolvers(args) + createBlockPhotoResolvers(args) } /* diff --git a/gatsby/generic-pages/content-blocks.ts b/gatsby/generic-pages/content-blocks.ts index 181163d7e..752cc6bfb 100644 --- a/gatsby/generic-pages/content-blocks.ts +++ b/gatsby/generic-pages/content-blocks.ts @@ -22,12 +22,14 @@ export const schema = ` } type DABlockImage implements Node { - asset: String! + relativePath: String! + alt: String! + image: ImageSharp! + caption: String attribution: String! dateUploaded: Date date: Date - altText: String! tags: [String!]! alignmentPhoto: String @@ -152,21 +154,22 @@ export const deriveImageBlockNode: DeriveBlockFn = ( parentId, { createNodeId, createContentDigest }, ) => { - const altText = getStringProperty(block, 'altText') + const alt = getStringProperty(block, 'altText') return { - asset: getStringProperty(block, 'asset'), + relativePath: getStringProperty(block, 'asset'), + alt: alt, + caption: getStringProperty(block, 'caption'), attribution: getStringProperty(block, 'attribution'), dateUploaded: getDateProperty(block, 'dateUploaded'), date: block?.date ? getDateProperty(block, 'date') : undefined, - altText: altText, tags: getArrayProperty(block, 'tags'), alignmentPhoto: getStringProperty(block, 'alignmentPhoto'), alignmentCaption: getStringProperty(block, 'alignmentCaption'), // Gatsby Fields - id: createNodeId(`DABlockImage - ${altText}`), + id: createNodeId(`DABlockImage - ${alt}`), parent: parentId, children: [], internal: { diff --git a/gatsby/generic-pages/resolvers.ts b/gatsby/generic-pages/resolvers.ts new file mode 100644 index 000000000..7e96c8902 --- /dev/null +++ b/gatsby/generic-pages/resolvers.ts @@ -0,0 +1,11 @@ +import { CreateResolversArgs } from 'gatsby' +import { imageSharpResolver } from '../create-resolvers' + +export const createBlockPhotoResolvers = (args: CreateResolversArgs) => { + const { createResolvers, getNode } = args + createResolvers({ + DABlockImage: { + image: imageSharpResolver(getNode, 'relativePath'), + }, + }) +} diff --git a/src/components/section/blocks/BlockImage.tsx b/src/components/section/blocks/BlockImage.tsx index 23e1777d0..0e28bbf65 100644 --- a/src/components/section/blocks/BlockImage.tsx +++ b/src/components/section/blocks/BlockImage.tsx @@ -1,3 +1,4 @@ +import { GatsbyImage } from 'gatsby-plugin-image' import { FC } from 'react' import { BlockImage as BlockImageType } from '../../../types/generic-page.d' @@ -7,5 +8,13 @@ type BlockImageProps = { } export const BlockImage: FC = ({ block, className }) => { - return
image
+ return ( +
+ +
+ ) } diff --git a/src/pages/{DAPageGeneric.slug}.tsx b/src/pages/{DAPageGeneric.slug}.tsx index 761e975d9..b81be0216 100644 --- a/src/pages/{DAPageGeneric.slug}.tsx +++ b/src/pages/{DAPageGeneric.slug}.tsx @@ -81,12 +81,19 @@ export const query = graphql` type } - asset + image { + gatsbyImageData( + width: 640 + aspectRatio: 1.2 + transformOptions: { fit: COVER } + ) + } + alt + caption attribution dateUploaded date - altText tags alignmentPhoto diff --git a/src/types/generic-page.d.ts b/src/types/generic-page.d.ts index 991058541..93acbedef 100644 --- a/src/types/generic-page.d.ts +++ b/src/types/generic-page.d.ts @@ -1,4 +1,5 @@ import { Node, NodeInput } from 'gatsby' +import { GatsbyImage } from 'gatsby-plugin-image' import { LinksList, UpdatesList } from './list.d' /* @@ -190,7 +191,15 @@ export interface BlockImage { /** * relative path to media file */ - asset: string + relativePath: string + /** + * Alternative text + */ + alt: string + /** + * Image process by sharp + */ + image: GatsbyImage caption?: string @@ -201,7 +210,6 @@ export interface BlockImage { dateUploaded?: Date date?: Date - altText: string tags: string[] alignmentPhoto?: 'Left' | 'Center' | 'Right' diff --git a/src/types/generic-page.test-helpers.ts b/src/types/generic-page.test-helpers.ts index e527adc9f..4f2717110 100644 --- a/src/types/generic-page.test-helpers.ts +++ b/src/types/generic-page.test-helpers.ts @@ -478,11 +478,12 @@ export const getBlockImageData = (props?: Record) => { ...props, asset: '', + alt: 'A Fake Image', + caption: 'An Image Block', attribution: 'Distribute Aid', dateUploaded: new Date(2020, 9, 8), date: new Date(2020, 9, 8), - altText: 'A Fake Image', tags: ['a tag'], alignmentPhoto: 'Left', @@ -498,12 +499,14 @@ export const getBlockImageNodeInput = (props?: Record) => { parent: 'parent-id', children: [], - asset: '', + relativePath: '', + alt: 'A Fake Image', + image: undefined, + caption: 'An Image Block', attribution: 'Distribute Aid', dateUploaded: new Date(2020, 9, 8), date: new Date(2020, 9, 8), - altText: 'A Fake Image', tags: ['a tag'], alignmentPhoto: 'Left', @@ -526,12 +529,15 @@ export const getBlockImageNode = (props?: Record) => { parent: 'parent-id', children: [], + relativePath: '', + alt: 'A Fake Image', + image: undefined, + asset: '', caption: 'An Image Block', attribution: 'Distribute Aid', dateUploaded: new Date(2020, 9, 8), date: new Date(2020, 9, 8), - altText: 'A Fake Image', tags: ['a tag'], alignmentPhoto: 'Left', From c6703b5e7182321faadd6c21aff1ec9a1e89499e Mon Sep 17 00:00:00 2001 From: Taylor Fairbank Date: Thu, 27 Apr 2023 19:02:26 +0000 Subject: [PATCH 6/6] fix: generic page image tests --- src/components/section/ContentBlock.spec.tsx | 8 ++++---- src/components/section/blocks/BlockImage.spec.tsx | 4 ++-- src/components/section/blocks/BlockImage.tsx | 2 +- src/types/generic-page.d.ts | 9 +++++++-- src/types/generic-page.test-helpers.ts | 5 ++--- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/components/section/ContentBlock.spec.tsx b/src/components/section/ContentBlock.spec.tsx index 7bcf1d00f..097763840 100644 --- a/src/components/section/ContentBlock.spec.tsx +++ b/src/components/section/ContentBlock.spec.tsx @@ -20,7 +20,7 @@ describe('Blocks', () => { }) it('can render multiple blocks', () => { - const { getByText, getByAltText } = render() + const { getByText, getByTestId } = render() const titleElem = getByText('My Title') expect(titleElem).toBeTruthy() @@ -31,7 +31,7 @@ describe('Blocks', () => { const youTubeElem = getByText('My video.') expect(youTubeElem).toBeTruthy() - const imageElem = getByAltText('My Alt') + const imageElem = getByTestId('BlockImage') expect(imageElem).toBeTruthy() }) @@ -96,8 +96,8 @@ describe('Block', () => { it('can render an image block', () => { const block = factory.getBlockImageNode({ alt: 'My Alt' }) - const { getByAltText } = render() - const imageElem = getByAltText('My Alt') + const { getByTestId } = render() + const imageElem = getByTestId('BlockImage') expect(imageElem).toBeTruthy() }) diff --git a/src/components/section/blocks/BlockImage.spec.tsx b/src/components/section/blocks/BlockImage.spec.tsx index ba21d9ac0..1cd0ce398 100644 --- a/src/components/section/blocks/BlockImage.spec.tsx +++ b/src/components/section/blocks/BlockImage.spec.tsx @@ -5,8 +5,8 @@ import { BlockImage } from './BlockImage' describe('BlockImage', () => { it('renders the image and related content', () => { const block = factory.getBlockImageNode({ alt: 'My Alt' }) - const { getByAltText } = render() - const title = getByAltText('My Alt') + const { getByTestId } = render() + const title = getByTestId('BlockImage') expect(title).toBeTruthy() }) }) diff --git a/src/components/section/blocks/BlockImage.tsx b/src/components/section/blocks/BlockImage.tsx index 0e28bbf65..302752256 100644 --- a/src/components/section/blocks/BlockImage.tsx +++ b/src/components/section/blocks/BlockImage.tsx @@ -9,7 +9,7 @@ type BlockImageProps = { export const BlockImage: FC = ({ block, className }) => { return ( -
+
) => { ...props, asset: '', - alt: 'A Fake Image', + altText: 'A Fake Image', caption: 'An Image Block', attribution: 'Distribute Aid', @@ -501,7 +501,6 @@ export const getBlockImageNodeInput = (props?: Record) => { relativePath: '', alt: 'A Fake Image', - image: undefined, caption: 'An Image Block', attribution: 'Distribute Aid', @@ -531,7 +530,7 @@ export const getBlockImageNode = (props?: Record) => { relativePath: '', alt: 'A Fake Image', - image: undefined, + image: { gatsbyImageData: undefined }, asset: '', caption: 'An Image Block',