From 9b39776c9240e6faebdcb9e4987d01a745908f7f Mon Sep 17 00:00:00 2001 From: Stephanie Smith Date: Thu, 29 Aug 2024 13:28:22 -0700 Subject: [PATCH] feature: EDU Multimedia and Gallery templates (#583) * adding PageEduMultimediaDetail template * adjusting alighment of step number on edu lesson page * adding PageEduGalleryDetail and tweaking PageEduMultimediaDetail * tweaking jump menu on PageEduGalleryDetail * updating constants to reflect all edu resource types * fixing vue build error --- .../BlockStreamfield/BlockStreamfield.vue | 3 + .../NavSecondary/NavSecondaryDropdown.vue | 4 +- packages/vue/src/constants.ts | 40 +- .../PageEduGalleryDetail.stories.js | 106 +++++ .../PageEduGalleryDetail.vue | 238 ++++++++++ .../PageEduLesson/PageEduLesson.stories.js | 14 + .../PageEduLesson/PageEduLessonSection.vue | 13 +- .../PageEduMultimediaDetail.stories.js | 176 +++++++ .../PageEduMultimediaDetail.vue | 434 ++++++++++++++++++ packages/vue/src/utils/getHeadingId.ts | 3 +- 10 files changed, 1021 insertions(+), 10 deletions(-) create mode 100644 packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.js create mode 100644 packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue create mode 100644 packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.stories.js create mode 100644 packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.vue diff --git a/packages/vue/src/components/BlockStreamfield/BlockStreamfield.vue b/packages/vue/src/components/BlockStreamfield/BlockStreamfield.vue index a26cc6cc..74da17e7 100644 --- a/packages/vue/src/components/BlockStreamfield/BlockStreamfield.vue +++ b/packages/vue/src/components/BlockStreamfield/BlockStreamfield.vue @@ -361,6 +361,9 @@ export default defineComponent({ &.container { @apply px-0; } + > div.lg\:px-0.px-4 { + @apply px-0; + } } .BlockInlineImage { diff --git a/packages/vue/src/components/NavSecondary/NavSecondaryDropdown.vue b/packages/vue/src/components/NavSecondary/NavSecondaryDropdown.vue index 38eb7236..72734221 100644 --- a/packages/vue/src/components/NavSecondary/NavSecondaryDropdown.vue +++ b/packages/vue/src/components/NavSecondary/NavSecondaryDropdown.vue @@ -121,12 +121,12 @@ export default defineComponent({ return this.invert ? { 'mr-auto text-white font-bold secondary-root': index === 0, - 'text-white font-semibold !pt-[.6rem]': index !== 0, + 'text-white font-semibold mt-[.2rem]': index !== 0, '-open': this.dropdownVisible } : { 'mr-auto text-primary font-semibold secondary-root': index === 0, - 'text-gray-dark font-medium !pt-[.6rem]': index !== 0, + 'text-gray-dark font-medium mt-[.2rem]': index !== 0, '-open': this.dropdownVisible } }, diff --git a/packages/vue/src/constants.ts b/packages/vue/src/constants.ts index 37a637f6..c8dc3905 100644 --- a/packages/vue/src/constants.ts +++ b/packages/vue/src/constants.ts @@ -1,6 +1,11 @@ import type { DictionaryInterface, PillDictionaryInterface } from './interfaces' export const eduMetadataDictionary: PillDictionaryInterface = { + EDUEventPage: { + variant: 'primary', + icons: 'primary', + type: 'event' + }, EDUCollectionsDetailPage: { label: 'Collection', variant: 'primary-inverted', @@ -25,10 +30,41 @@ export const eduMetadataDictionary: PillDictionaryInterface = { icons: 'primary', type: 'resource' }, - EDUEventPage: { + EDUStudentProjectPage: { + label: 'Student Project', + variant: 'secondary', + icons: 'secondary', + type: 'resource' + }, + EDUImageDetailPage: { + label: 'Image', variant: 'primary', icons: 'primary', - type: 'event' + type: 'resource' + }, + EDUInfographicDetailPage: { + label: 'Infographic', + variant: 'primary', + icons: 'primary', + type: 'resource' + }, + EDUDocumentDetailPage: { + label: 'Document', + variant: 'primary', + icons: 'primary', + type: 'resource' + }, + EDUVideoDetailPage: { + label: 'Video', + variant: 'primary', + icons: 'primary', + type: 'resource' + }, + EDUGalleryDetailPage: { + label: 'Gallery', + variant: 'secondary', + icons: 'secondary', + type: 'resource' } } diff --git a/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.js b/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.js new file mode 100644 index 00000000..db1a764a --- /dev/null +++ b/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.js @@ -0,0 +1,106 @@ +import { BlockKeyPointsData } from './../../../components/BlockKeyPoints/BlockKeyPoints.stories' +import { BlockLinkCardCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories.js' +import { EventsBlockLinkCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories' +import { AboutTheAuthorData } from './../../../components/AboutTheAuthor/AboutTheAuthor.stories' +import { BlockImageData } from './../../../components/BlockImage/BlockImage.stories' +import { BlockVideoData } from './../../../components/BlockVideo/BlockVideo.stories' +import { BlockVideoEmbedData } from './../../../components/BlockVideoEmbed/BlockVideoEmbed.stories' +import { BlockImageComparisonData } from './../../../components/BlockImageComparison/BlockImageComparison.stories' +import PageEduGalleryDetail from './PageEduGalleryDetail.vue' + +export default { + title: 'Templates/EDU/PageEduGalleryDetail', + component: PageEduGalleryDetail, + tags: ['!autodocs'], + parameters: { + html: { + root: '#storyDecorator' + }, + layout: 'fullscreen' + }, + excludeStories: /.*Data$/ +} + +const PageEduGalleryDetailData = { + title: 'Gallery Detail', + slug: 'gallery-item', + url: '/resources/gallery/gallery-item', + lastPublishedAt: '2024-08-22T02:33:13.507206+00:00', + thumbnailImage: { + alt: '', + original: 'https://picsum.photos/512/288' + }, + authors: AboutTheAuthorData, + + body: [ + { + blockType: 'RichTextBlock', + value: + '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.

Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.

\n' + } + ], + relatedLinks: [ + { + blockType: 'RelatedLinksBlock', + heading: 'Related Links', + links: [ + { + document: null, + externalLink: 'http://www.google.com', + page: null, + text: 'Lorem ipsum dolor' + }, + { + document: null, + externalLink: 'http://www.google.com', + page: null, + text: 'Sit amet consectatur' + } + ] + } + ], + relatedContent: EventsBlockLinkCarouselData, + exploreMore: [...BlockLinkCardCarouselData, ...EventsBlockLinkCarouselData] +} +// stories +export const BaseStory = { + name: 'PageEduGalleryDetail', + args: { + data: { + __typename: 'EDUGalleryDetailPage', + ...PageEduGalleryDetailData, + showJumpMenu: true, + overviewString: '

Overview about the gallery.

', + galleryItems: [ + { + blockId: `${Math.random().toString(36).slice(2)}`, + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [{ ...BlockImageData, blockType: 'ImageBlock' }] + }, + { + blockId: `${Math.random().toString(36).slice(2)}`, + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockImageComparisonData] + }, + { + blockId: `${Math.random().toString(36).slice(2)}`, + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockVideoData.block] + }, + { + blockId: `${Math.random().toString(36).slice(2)}`, + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockVideoEmbedData.data] + } + ] + } + } +} diff --git a/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue b/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue new file mode 100644 index 00000000..d07ddf32 --- /dev/null +++ b/packages/vue/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue @@ -0,0 +1,238 @@ + + + diff --git a/packages/vue/src/templates/edu/PageEduLesson/PageEduLesson.stories.js b/packages/vue/src/templates/edu/PageEduLesson/PageEduLesson.stories.js index 28b3cf70..e5e47988 100644 --- a/packages/vue/src/templates/edu/PageEduLesson/PageEduLesson.stories.js +++ b/packages/vue/src/templates/edu/PageEduLesson/PageEduLesson.stories.js @@ -181,7 +181,21 @@ export const BaseStory = { steps: [ { blocks: [ + // { + // blockType: 'HeadingBlock', + // heading: 'Heading Text', + // level: 'h3', + // size: 'h3', + // blockId: `${Math.random().toString(36).slice(2)}` + // }, ...BlockStreamfieldMinimalData.body, + { + blockType: 'HeadingBlock', + heading: 'Heading Text', + level: 'h3', + size: 'h3', + blockId: `${Math.random().toString(36).slice(2)}` + }, { blockType: 'RichTextBlock', diff --git a/packages/vue/src/templates/edu/PageEduLesson/PageEduLessonSection.vue b/packages/vue/src/templates/edu/PageEduLesson/PageEduLessonSection.vue index cf704009..a0035766 100644 --- a/packages/vue/src/templates/edu/PageEduLesson/PageEduLessonSection.vue +++ b/packages/vue/src/templates/edu/PageEduLesson/PageEduLessonSection.vue @@ -139,7 +139,7 @@ const anchorId = computed(() => { } .PageEduProcedureSectionSingleStep { li:not(:last-of-type) .BlockStreamfield { - @apply -mb-5 lg:-mb-10; + @apply -mb-5; } } ol.PageEduProcedureSectionSingleStep { @@ -148,7 +148,7 @@ const anchorId = computed(() => { @apply relative w-full; counter-increment: step; &::before { - @apply relative block w-[45rem] mx-auto h-0 pl-3; + @apply relative block w-[45rem] mx-auto h-0 pl-1; content: counter(step) '. '; // mimicking .text-body-lg font-size: pxToRem(18); @@ -163,13 +163,13 @@ const anchorId = computed(() => { } @screen md { &::before { - @apply w-[50rem]; + @apply w-[51.5rem]; font-size: pxToRem(20); } } @screen lg { &::before { - @apply w-[47rem] pl-0; + @apply w-[46rem] pl-0; font-size: pxToRem(21); } } @@ -179,6 +179,11 @@ const anchorId = computed(() => { font-size: pxToRem(22); } } + @screen 2xl { + &::before { + // @apply w-[58.5rem]; + } + } } } } diff --git a/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.stories.js b/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.stories.js new file mode 100644 index 00000000..1040ff9f --- /dev/null +++ b/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.stories.js @@ -0,0 +1,176 @@ +import { BlockKeyPointsData } from './../../../components/BlockKeyPoints/BlockKeyPoints.stories' +import { BlockLinkCardCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories.js' +import { EventsBlockLinkCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories' +import { AboutTheAuthorData } from './../../../components/AboutTheAuthor/AboutTheAuthor.stories' +import { BlockImageData } from './../../../components/BlockImage/BlockImage.stories' +import { BlockVideoData } from './../../../components/BlockVideo/BlockVideo.stories' +import { BlockVideoEmbedData } from './../../../components/BlockVideoEmbed/BlockVideoEmbed.stories' +import { BlockImageComparisonData } from './../../../components/BlockImageComparison/BlockImageComparison.stories' +import PageEduMultimediaDetail from './PageEduMultimediaDetail.vue' + +export default { + title: 'Templates/EDU/PageEduMultimediaDetail', + component: PageEduMultimediaDetail, + tags: ['!autodocs'], + parameters: { + html: { + root: '#storyDecorator' + }, + layout: 'fullscreen' + }, + excludeStories: /.*Data$/ +} + +const PageEduMultimediaDetailData = { + title: 'Media Item', + slug: 'media-item', + url: '/resources/media/media-item', + lastPublishedAt: '2024-08-22T02:33:13.507206+00:00', + thumbnailImage: { + alt: '', + original: 'https://picsum.photos/512/288' + }, + authors: AboutTheAuthorData, + + body: [ + { + blockType: 'RichTextBlock', + value: + '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.

Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.

\n' + } + ], + relatedLinks: [ + { + blockType: 'RelatedLinksBlock', + heading: 'Related Links', + links: [ + { + document: null, + externalLink: 'http://www.google.com', + page: null, + text: 'Lorem ipsum dolor' + }, + { + document: null, + externalLink: 'http://www.google.com', + page: null, + text: 'Sit amet consectatur' + } + ] + } + ], + relatedContent: EventsBlockLinkCarouselData, + exploreMore: [...BlockLinkCardCarouselData, ...EventsBlockLinkCarouselData] +} +// stories +export const BaseStory = { + name: 'Image', + args: { + data: { + __typename: 'EDUImageDetailPage', + ...PageEduMultimediaDetailData, + imageAsHero: BlockImageData.image, + heroImageCaption: 'This is the hero image caption' + } + } +} + +export const Infographic = { + args: { + data: { + __typename: 'EDUInfographicDetailPage', + ...PageEduMultimediaDetailData, + imageAsHero: BlockImageData.image, + heroImageCaption: 'This is the hero image caption for the infographic' + } + } +} + +export const Video = { + args: { + data: { + __typename: 'EDUVideoDetailPage', + ...PageEduMultimediaDetailData, + video: [BlockVideoData.block], + transcript: `

Preparing to Land Perseverance

+

The following tests, conducted from 2017-2020, helped prepare NASA's Perseverance rover for its landing on Mars.

+

[music]

+

Centrifuge Spin Test

` + } + } +} + +export const VideoEmbed = { + args: { + data: { + __typename: 'EDUVideoDetailPage', + ...PageEduMultimediaDetailData, + video: [BlockVideoEmbedData.data], + transcript: `

Preparing to Land Perseverance

+

The following tests, conducted from 2017-2020, helped prepare NASA's Perseverance rover for its landing on Mars.

+

[music]

+

Centrifuge Spin Test

+

Santa Clarita, CA June 2019

+

[music]

+

Parachute Firing Test

+

Moses Lake, WA May 2019

+

[music]

+

[mortar firing]

+

[mortar firing]

+

[clapping]

` + } + } +} + +export const Document = { + args: { + data: { + __typename: 'EDUDocumentDetailPage', + ...PageEduMultimediaDetailData, + heroImage: { + ...BlockImageData.image + }, + heroImageCaption: 'This is the hero image caption for the document', + document: { + url: 'https://jpl.nasa.gov' + }, + credit: '

Document credit attribution

' + } + } +} + +export const Gallery = { + args: { + data: { + __typename: 'EDUGalleryDetailPage', + ...PageEduMultimediaDetailData, + galleryItems: [ + { + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockImageData.image] + }, + { + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockImageComparisonData] + }, + { + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockVideoData.block] + }, + { + heading: 'Gallery Item Heading', + description: + '

Description that is rich text.

', + media: [BlockVideoEmbedData.data] + } + ], + showJumpMenu: true + } + } +} diff --git a/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.vue b/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.vue new file mode 100644 index 00000000..c793586c --- /dev/null +++ b/packages/vue/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.vue @@ -0,0 +1,434 @@ + + + diff --git a/packages/vue/src/utils/getHeadingId.ts b/packages/vue/src/utils/getHeadingId.ts index f34f940b..7c3f70ab 100644 --- a/packages/vue/src/utils/getHeadingId.ts +++ b/packages/vue/src/utils/getHeadingId.ts @@ -1,5 +1,4 @@ import { camelCase } from 'lodash' -import { type HeadingLevel } from '../components/BaseHeading/BaseHeading.vue' -export const getHeadingId = (heading: HeadingLevel, blockId?: string) => { +export const getHeadingId = (heading: string, blockId?: string) => { return 'anchor_' + camelCase(heading) + (blockId ? '_' + camelCase(blockId) : '') }