Skip to content

Commit

Permalink
Merge branch 'main' into APPS-2974-title-tag-in-template
Browse files Browse the repository at this point in the history
  • Loading branch information
farosFreed authored Oct 16, 2024
2 parents 054b0f6 + f9b150c commit 8e2387b
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 70 deletions.
11 changes: 11 additions & 0 deletions cypress/e2e/collectionDetailPage.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
describe('Collection Detail Page', () => {
it('Visits a Collection Detail Page', () => {
cy.visit('/collections/test-get-used-to-it')
cy.getByData('breadcrumb').should('be.visible')
// sharebutton should exist
cy.getByData('share-button').should('exist')
// cta should be in sidebar w specific data
cy.getByData('sidebar-cta').should('exist')
cy.percySnapshot('collectiondetailpage', { widths: [768, 992, 1200] })
})
})
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"lodash": "^4.17.21",
"nuxt-graphql-request": "^7.0.5",
"sass": "^1.66.1",
"ucla-library-design-tokens": "^5.22.0",
"ucla-library-website-components": "3.28.0"
"ucla-library-design-tokens": "^5.27.0",
"ucla-library-website-components": "3.29.1"
}
}
1 change: 1 addition & 0 deletions pages/blog/[slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ useHead({
<FlexibleMediaGalleryNewLightbox
data-test="image-carousel"
:items="parsedCarouselData"
:inline="true"
>
<template #default="slotProps">
<BlockTag
Expand Down
147 changes: 118 additions & 29 deletions pages/collections/[slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// COMPONENT RE-IMPORTS
// TODO: remove when we have implemented component library as a module
// https://nuxt.com/docs/guide/directory-structure/components#library-authors
import { CardMeta, DividerWayFinder, FlexibleMediaGalleryNewLightbox, NavBreadcrumb, ResponsiveImage, RichText, SectionTeaserCard, SectionWrapper, TwoColLayoutWStickySideBar } from 'ucla-library-website-components'
import { BlockCallToAction, CardMeta, DividerWayFinder, NavBreadcrumb, ResponsiveImage, RichText, SectionTeaserCard, SectionWrapper, TwoColLayoutWStickySideBar, VideoEmbed } from 'ucla-library-website-components'
// HELPERS
import _get from 'lodash/get'
Expand Down Expand Up @@ -39,7 +39,7 @@ const page = ref(_get(data.value, 'ftvaCollection', {}))
watch(data, (newVal, oldVal) => {
console.log('In watch preview enabled, newVal, oldVal', newVal, oldVal)
page.value = _get(newVal, 'ftvaEvent', {})
page.value = _get(newVal, 'ftvaCollection', {})
})
// DATA PARSING
Expand All @@ -50,15 +50,41 @@ const parsedImage = computed(() => {
}
return page.value.imageCarousel
})
// Combine the categories into a String
const parsedCollectionType = computed(() => {
if (page.value.ftvaCollectionType) {
// split camelCase items in list and join with space, then join list with comma
return page.value.ftvaCollectionType.map(str => str.split(/(?=[A-Z])/).join(' ')).join(', ')
// Transform data for Carousel
const parsedCarouselData = computed(() => {
// map image to item, map creditText to credit
return parsedImage.value.map((rawItem, index) => {
return {
item: [{ ...rawItem.image[0], kind: 'image' }], // Carousels on this page are always images, no videos
credit: rawItem?.creditText,
}
})
})
// Map icon names to svg names for infoBlock
const parsedInfoBlockIconLookup = {
'icon-download': 'svg-call-to-action-ftva-pdf',
'icon-external-link': 'svg-call-to-action-ftva-info'
}
const parsedInfoBlock = computed(() => {
// fail gracefully if data does not exist (server-side)
if (!page.value.infoBlock || page.value.infoBlock.length === 0) {
return null
}
return null
return page.value.infoBlock.map((item, index) => {
const parsedIcon = parsedInfoBlockIconLookup[item?.icon] ? parsedInfoBlockIconLookup[item.icon] : parsedInfoBlockIconLookup['icon-external-link']
return {
text: item.text,
icon: parsedIcon
}
})
})
const parsedRelatedCollectionsHeader = computed(() => {
// fail gracefully if data does not exist (server-side)
if (!page.value.sectionTitle) {
return 'Related Collections'
}
return page.value.sectionTitle ? page.value.sectionTitle : 'Related Collections'
})
const parsedRelatedCollections = computed(() => {
// fail gracefully if data does not exist (server-side)
if (!page.value.ftvaRelatedCollections) {
Expand All @@ -68,14 +94,25 @@ const parsedRelatedCollections = computed(() => {
const relatedCollections = page.value.ftvaRelatedCollections.map((item, index) => {
return {
...item,
to: `/${item.uri}`, // remove 'collection/' from uri
sectionHandle: 'ftvaEventSeries',
to: `/${item.uri}`,
category: 'collection',
bylineOne: item.richText,
image: item.ftvaImage && item.ftvaImage.length > 0 ? item.ftvaImage[0] : null,
}
})
return relatedCollections
})
const parsedRelatedCollectionsText = computed(() => {
// TODO does this fail gracefully?
const text = _get(page.value, 'viewAllSectionLink[0].viewAllText', '')
return text || 'View All'
})
// TODO goes to /collections/[uri] - is this correct check with UX?
const parsedRelatedCollectionsLink = computed(() => {
// TODO does this fail gracefully?
const link = _get(page.value, 'viewAllSectionLink[0].viewAllLink[0].uri', '')
return link || '/collections'
})
useHead({
title: page.value ? page.value.title : '... loading',
Expand All @@ -95,6 +132,7 @@ useHead({
>
<div class="one-column">
<NavBreadcrumb
data-test="breadcrumb"
class="breadcrumb"
:title="page?.title"
to="/collections"
Expand All @@ -112,50 +150,90 @@ useHead({
{{ parsedImage[0]?.creditText }}
</template>
</ResponsiveImage>
<div
v-else
class="lightbox-container"
>
<FlexibleMediaGalleryNewLightbox
data-test="image-carousel"
:items="parsedCarouselData"
:inline="true"
>
<template #default="slotProps">
<BlockTag
data-test="credit-text"
:label="parsedCarouselData[slotProps.selectionIndex]?.creditText"
/>
</template>
</FlexibleMediaGalleryNewLightbox>
</div>
</div>
<TwoColLayoutWStickySideBar>
<template #primaryTop>
<CardMeta
:category="parsedCollectionType"
category="Collection"
:title="page?.title"
>
<template #sharebutton>
<ButtonDropdown
data-test="share-button"
button-title="Share"
:has-icon="true"
:dropdown-list="socialList.dropdownList"
/>
</template>
</CardMeta>
<RichText
v-if="page?.richText"
:rich-text-content="page?.richText"
/>
</template>
<!-- Sidebar -->
<!-- may need to move to diff slot? -->
<template #sidebarTop>
{{ page.infoBlock }}
<BlockCallToAction
data-test="sidebar-cta"
:use-global-data="true"
:is-centered="false"
/>
</template>
<template #primaryMid>
<RichText
v-if="page?.richText"
:rich-text-content="page?.richText"
/>
<DividerWayFinder v-if="page.videoEmbed" />
<VideoEmbed
v-if="page.videoEmbed"
:trailer="page.videoEmbed"
/>
<DividerWayFinder v-if="parsedInfoBlock" />
<div
v-if="parsedInfoBlock"
class="cta-block"
>
<BlockCallToAction
v-for="(item) in parsedInfoBlock"
:key="item.text.concat(10)"
:svg-name="item.icon"
:text="item.text"
:is-centered="false"
/>
</div>
</template>
</TwoColLayoutWStickySideBar>
<div>
{{ page }}
</div>
<SectionWrapper
v-if="parsedRelatedCollections && parsedRelatedCollections.length > 0"
theme="paleblue"
:section-title="page.sectionTitle"
:section-title="parsedRelatedCollectionsHeader"
class="series-section-wrapper"
>
<template #top-right>
<!-- todo replace with data -->
<nuxt-link to="/series">
View All Series <span style="font-size:1.5em;"> &#8250;</span>
<nuxt-link
v-if="parsedRelatedCollectionsLink"
:to="parsedRelatedCollectionsLink"
>
{{ parsedRelatedCollectionsText }} <span style="font-size:1.5em;"> &#8250;</span>
</nuxt-link>
</template>
<SectionTeaserCard
class="other-series-section"
class="related-collections-card"
:items="parsedRelatedCollections"
/>
</SectionWrapper>
Expand All @@ -165,7 +243,6 @@ useHead({
.page-collection-detail {
position: relative;
// TODO move this element to global mixin or something, its on every detail page
&:before {
content: '';
position: absolute;
Expand All @@ -177,7 +254,6 @@ useHead({
z-index: -1;
}
// TODO global?
.one-column {
width: 100%;
max-width: var(--max-width);
Expand All @@ -188,7 +264,6 @@ useHead({
}
}
// TODO global?
.full-width {
width: 100%;
background-color: var(--pale-blue);
Expand All @@ -198,5 +273,19 @@ useHead({
background-color: var(--pale-blue);
}
}
.cta-block {
:deep(.block-call-to-action) {
&:not(:last-child) {
margin-bottom: 16px;
}
}
}
.related-collections-card {
:deep(.byline-group) {
@include truncate(2);
}
}
}
</style>
2 changes: 1 addition & 1 deletion pages/collections/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ useHead({
<divider-general />
</div>
<code><strong>PAGE</strong> {{ page }}</code>
<!-- <code><strong>PAGE</strong> {{ page }}</code> -->
</section-wrapper>
</div>
</template>
Expand Down
27 changes: 0 additions & 27 deletions pages/series/[slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ const parsedOtherSeries = computed(() => {
})
return otherSeries
})
useHead({
title: page.value ? page.value.title : '... loading',
meta: [
Expand All @@ -151,32 +150,6 @@ useHead({
}
]
})
// MOBILE LOGIC
const globalStore = useGlobalStore()
const isMobile = ref(false)
watch(globalStore, (newVal, oldVal) => {
isMobile.value = globalStore.winWidth <= 750
})
// LAYOUT & STYLES
// TO DO THIS SECTION MAY BE WORTH ADDING TO 2 COL SIDE BAR LAYOUT
// Track height of sidebar and ensure main content as at least as tall
const sidebar = ref(null)
const primaryCol = ref(null)
watch([isMobile, sidebar], ([newValIsMobile, newValSidebar], [oldValGlobalStore, oldValSidebar]) => {
if (newValIsMobile === true) {
primaryCol.value.style.minHeight = 'auto' // on mobile, reset height
} else {
primaryCol.value.style.minHeight = `${newValSidebar.clientHeight + 125}px`
}
}, { deep: true })
// globalstore state is lost when error page is generated , this is hack to repopulate state on client side
onMounted(() => {
isMobile.value = globalStore.winWidth <= 750 // 750px is the breakpoint for mobile
})
</script>
<template>
Expand Down
19 changes: 8 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8e2387b

Please sign in to comment.