Skip to content

Commit 2324b5f

Browse files
🎨 Fix presentation tool #3755 (#3811)
* 🎨 presentation tool * 🎨 presentation tool * 🎨 cleanup * 🎨 frame ancestor for dev
1 parent cf0e991 commit 2324b5f

9 files changed

Lines changed: 91 additions & 64 deletions

File tree

‎web/app/[locale]/(pages)/[...slug]/page.tsx‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { magazineSlug, newsSlug } from '@energyvision/shared/satelliteConfig'
2+
import { stegaClean } from '@sanity/client/stega'
23
import type { Metadata } from 'next'
34
import dynamic from 'next/dynamic'
5+
import { cookies, draftMode } from 'next/headers'
46
import { notFound } from 'next/navigation'
57
import { setRequestLocale } from 'next-intl/server'
68
import { getValidLanguagesLocales } from '@/languageConfig'
@@ -20,7 +22,7 @@ import Header from '@/sections/Header/Header'
2022

2123
type Props = {
2224
params: Promise<{ slug: string[]; locale: string }>
23-
searchParams: Promise<{ [key: string]: string[] | undefined }>
25+
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
2426
}
2527
const MagazinePage = dynamic(() => import('@/templates/magazine/MagazinePage'))
2628
const EventPage = dynamic(() => import('@/templates/event/Event'))
@@ -74,11 +76,14 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
7476

7577
export default async function Page({ params }: Props) {
7678
const { slug, locale } = await params
79+
/* const isInPresentationToolContext =
80+
(await cookies()).get('preview-fetch-dest')?.value === 'iframe' */
81+
const { isEnabled: isDraftMode } = await draftMode()
7782

7883
if (!getValidLanguagesLocales().includes(locale)) notFound()
7984

8085
setRequestLocale(locale)
81-
86+
let pageContent = null
8287
const [siteMenuResult, pageResults] = await Promise.all([
8388
routeSanityFetch({
8489
query: Flags.HAS_FANCY_MENU ? globalMenuQuery : simpleMenuQuery,
@@ -91,8 +96,15 @@ export default async function Page({ params }: Props) {
9196
locale,
9297
}),
9398
])
99+
pageContent = pageResults
100+
101+
if (isDraftMode) {
102+
//Later when inside presentation tool, cant clean as it doesnt work with visual editing, must filter props together with visual editing,
103+
console.log('Clean page data for stega')
104+
pageContent = stegaClean(pageResults)
105+
}
94106

95-
const { headerData, pageData } = pageResults
107+
const { headerData, pageData } = pageContent
96108
const { data: siteMenuData } = siteMenuResult || {}
97109
if (Object.keys(pageData).length === 0) notFound()
98110

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use client'
2+
3+
import dynamic from 'next/dynamic'
4+
import { useIsPresentationTool } from 'next-sanity/hooks'
5+
6+
const VisualEditing = dynamic(() =>
7+
import('next-sanity/visual-editing').then(mod => mod.VisualEditing),
8+
)
9+
10+
export function ConditionalVisualEditing() {
11+
/** The webpage is inside an iframe, meaning its in the studio presentation tool tab and visual editing should be enabled */
12+
const isInsidePresentationTool = useIsPresentationTool()
13+
return isInsidePresentationTool ? <VisualEditing /> : null
14+
}

‎web/app/[locale]/layout.tsx‎

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { hasLocale, NextIntlClientProvider } from 'next-intl'
99
import { getTranslations, setRequestLocale } from 'next-intl/server'
1010
import { PageProvider } from '@/contexts/pageContext'
1111
import { getLocaleFromIso, getNameFromIso } from '@/sanity/helpers/localization'
12+
import { dataset } from '@/sanity/lib/api'
1213
import { routeSanityFetch, SanityLive } from '@/sanity/lib/live'
1314
import { footerAndErrorImageQuery } from '@/sanity/queries/footer'
1415
import Footer from '@/sections/Footer/Footer'
@@ -25,6 +26,10 @@ const equinor = localFont({
2526
],
2627
})
2728

29+
const DraftModeToolbar = dynamic(
30+
() => import('@/sections/DraftMode/DraftModeToolbar'),
31+
)
32+
2833
type Params = Promise<{ locale: string }>
2934

3035
/* export const metadata: Metadata = {
@@ -63,23 +68,7 @@ export default async function LocaleLayout({
6368
})
6469

6570
const { errorImage, ...footerData } = footerAndErrorImageData || {}
66-
67-
async function loadVisualEditing() {
68-
if ((await draftMode()).isEnabled) {
69-
const DraftModeToolbar = dynamic(
70-
() => import('@/sections/DraftMode/DraftModeToolbar'),
71-
)
72-
const VisualEditing = dynamic(() =>
73-
import('next-sanity/visual-editing').then(mod => mod.VisualEditing),
74-
)
75-
return (
76-
<>
77-
<DraftModeToolbar />
78-
<VisualEditing />
79-
</>
80-
)
81-
}
82-
}
71+
const isPreview = (await draftMode()).isEnabled
8372

8473
return (
8574
<html lang={locale} className={`${equinor.className} `}>
@@ -91,15 +80,21 @@ export default async function LocaleLayout({
9180
{t('skipToContent') ?? 'Skip to main content'}
9281
</NextLink>
9382
<SanityLive />
94-
{loadVisualEditing()}
83+
{isPreview && (
84+
<>
85+
<DraftModeToolbar />
86+
{/* Must first filter all conditional rendering props in the page content, otherwise the visual editing will not work correctly inside presentation tool. This is a big job and will be done later. For now, we will not render the visual editing inside the presentation tool.
87+
<ConditionalVisualEditing /> */}
88+
</>
89+
)}
9590
<NextIntlClientProvider>
9691
<PageProvider initialErrorImage={errorImage}>{children}</PageProvider>
9792
<Footer {...footerData} />
9893
<GoToTopButton />
9994
</NextIntlClientProvider>
10095
</body>
10196
{/** TODO look into scripts */}
102-
{
97+
{!(isPreview || dataset === 'global-development') && (
10398
<Script
10499
src='https://consent.cookiebot.com/uc.js'
105100
id='Cookiebot'
@@ -108,7 +103,7 @@ export default async function LocaleLayout({
108103
data-blockingmode='auto'
109104
data-culture={locale === 'nb-NO' ? 'nb' : getLocaleFromIso(locale)}
110105
/>
111-
}
106+
)}
112107
<GoogleTagManagerHead />
113108
<SiteImprove />
114109
</html>

‎web/app/[locale]/page.tsx‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { stegaClean } from '@sanity/client/stega'
12
import type { Metadata } from 'next'
3+
import { draftMode } from 'next/headers'
24
import { notFound } from 'next/navigation'
35
import { setRequestLocale } from 'next-intl/server'
46
import { OrganizationJsonLd } from 'next-seo'
@@ -16,13 +18,9 @@ import { FriendlyCaptchaSdkWrapper } from './FriendlyCaptchaWrapper'
1618

1719
type Props = {
1820
params: Promise<{ slug: string; locale: string }>
19-
searchParams: Promise<{ [key: string]: string[] | undefined }>
21+
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
2022
}
2123

22-
/*export async function generateStaticParams() {
23-
return languages.map(language => ({ locale: language.iso }))
24-
}*/
25-
2624
export async function generateMetadata({ params }: Props): Promise<Metadata> {
2725
const { locale } = await params
2826
const { data: metaData }: { data: any } = await routeSanityFetch({
@@ -39,11 +37,14 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
3937

4038
export default async function Home({ params }: Props) {
4139
const { locale, slug } = await params
40+
//const isInPresentationToolContext =
41+
// (await cookies()).get('preview-fetch-dest')?.value === 'iframe'
4242
// Enable static rendering
4343
setRequestLocale(locale)
44+
const { isEnabled: isDraftMode } = await draftMode()
4445

4546
if (!languages.map(it => it.iso).includes(locale)) notFound()
46-
47+
let pageContent = null
4748
const [siteMenuResult, homePageData] = await Promise.all([
4849
routeSanityFetch({
4950
query: Flags.HAS_FANCY_MENU ? globalMenuQuery : simpleMenuQuery,
@@ -57,8 +58,13 @@ export default async function Home({ params }: Props) {
5758
tags: ['homePage'],
5859
}),
5960
])
61+
pageContent = homePageData
62+
if (isDraftMode) {
63+
//Later when inside presentation tool, cant clean as it doesnt work with visual editing, must filter props together with visual editing,
64+
pageContent = stegaClean(homePageData)
65+
}
6066

61-
const { headerData, pageData } = homePageData
67+
const { headerData, pageData } = pageContent
6268
const { data: siteMenuData } = siteMenuResult || {}
6369

6470
if (!pageData) notFound()

‎web/app/api/draft/route.ts‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,42 @@ import { redirect } from 'next/navigation'
44
import type { NextRequest } from 'next/server'
55
import { client } from '@/sanity/lib/client'
66

7-
export async function GET(request: NextRequest, context: any) {
7+
export async function GET(request: NextRequest, _context: any) {
8+
//const secFetchDest = request.headers.get('sec-fetch-dest')
9+
//const referer = request.headers.get('referer')
810
const { isValid, redirectTo = '/' } = await validatePreviewUrl(
911
client,
1012
request.url,
1113
)
1214

15+
if (!isValid) {
16+
return new Response('Missing or invalid token', { status: 401 })
17+
}
18+
1319
let previewUrl = redirectTo
1420
if (redirectTo?.includes('/api/draft')) {
1521
const urlParts = redirectTo.split('/')
1622
previewUrl = `/${urlParts.at(-2)}/${urlParts.at(-1)}`
1723
}
1824

19-
if (!isValid) {
20-
return new Response('Missing or invalid token', { status: 401 })
21-
}
22-
2325
const draft = await draftMode()
2426
draft.enable()
2527

28+
/*
29+
Must stega filter page content props used for conditional rendering in the presentation tool, otherwise the page will not render correctly in the presentation tool.
30+
Something to do later as this will be a big job.
31+
setting a cookie for sec fetch dest to identify the request as coming from the presentation tool and the web is previewed inside it. Works SSR.
32+
const cookieStore = await cookies()
33+
if (secFetchDest) {
34+
cookieStore.set('preview-fetch-dest', secFetchDest, {
35+
path: '/',
36+
httpOnly: true,
37+
sameSite: 'lax',
38+
maxAge: 60,
39+
})
40+
} else {
41+
cookieStore.delete('preview-fetch-dest')
42+
} */
43+
2644
redirect(previewUrl)
27-
//redirect(`/preview/${id}`)
2845
}

‎web/sanity/lib/client.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ const sanityConfig: ClientConfig = {
1010
projectId,
1111
dataset,
1212
apiVersion,
13-
perspective: dataset === 'global-development' ? 'drafts' : 'published',
14-
useCdn: dataset !== 'global-development',
13+
//handled by definelive?
14+
//perspective: dataset === 'global-development' ? 'drafts' : 'published',
15+
useCdn: true,
1516
ignoreBrowserTokenWarning: dataset === 'global-development',
1617
requestTagPrefix: 'website', // to track usage on web in sanity console
1718
stega: {

‎web/sanity/lib/live.ts‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import type {
55
QueryParams,
66
} from 'next-sanity'
77
import { type DefinedFetchType, defineLive } from 'next-sanity/live'
8-
//import { dataset } from '@/languageConfig'
98
import { client } from './client'
10-
//import { tempSanityFetch } from './tempSanityFetch'
119
import { token } from './token'
1210

1311
export const { sanityFetch, SanityLive } = defineLive({
@@ -56,16 +54,5 @@ export type DefinedSanityFetchType = <
5654
}>
5755

5856
export const routeSanityFetch: DefinedFetchType = async query => {
59-
//const { tags, ...restQuery } = query
60-
61-
/*if (dataset === 'global-development') {
62-
//Dont use tags, use automated next tags
63-
//sanityFetch automatically sets fetch.next.tags for you using opaque tags generated by our backend, prefixed with sanity
64-
return sanityFetch(restQuery)
65-
}*/
6657
return sanityFetch(query)
67-
/* tempSanityFetch uses cache components which is not fully supported with next-intl
68-
https://aurorascharff.no/posts/implementing-nextjs-16-use-cache-with-next-intl-internationalization/
69-
return tempSanityFetch(query)
70-
*/
7158
}

‎web/sections/DraftMode/DraftModeToolbar.tsx‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
'use client'
2-
import { useIsPresentationTool } from 'next-sanity/hooks'
3-
import { useMemo, useTransition } from 'react'
2+
import { useEffect, useState, useTransition } from 'react'
43
import { disableDraftMode } from '@/app/_actions/disableDraftMode'
54
import { commonButtonStyling } from '@/core/Button'
65

76
export default function DraftModeToolbar() {
87
const [pending, startTransition] = useTransition()
9-
const isPresentationTool = useIsPresentationTool()
8+
const [isInsideTool, setIsInsideTool] = useState(false)
109

11-
const isInsideTool = useMemo(() => {
12-
return isPresentationTool
13-
}, [isPresentationTool])
10+
useEffect(() => {
11+
setIsInsideTool(window.self !== window.top)
12+
}, [])
1413
// Only show the disable draft mode button when outside of Presentation Tool
1514

1615
const disable = () => startTransition(() => disableDraftMode())

‎web/securityHeaders.ts‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { dataset } from './languageConfig'
99

1010
const isProduction = process.env.NODE_ENV === 'production'
1111

12-
const envs = ['preprod', 'prod', 'preprodv2']
12+
const envs = ['dev', 'preprod', 'prod', 'preprodv2']
1313
const localUrl =
1414
process.env.NODE_ENV === 'development' ? 'http://localhost:3333' : ''
1515
const globalUrl = dataset === 'global' ? 'https://equinor.sanity.studio' : ''
@@ -19,15 +19,11 @@ const studioUrls = envs.map(
1919
env =>
2020
`https://studio-${dataset}${env === 'preprodv2' ? `-upgrade` : ''}-equinor-web-sites-${env}.c2.radix.equinor.com`,
2121
)
22-
const studioV3Urls = [
23-
'http://studiov3-global-development-equinor-web-sites-dev.c2.radix.equinor.com',
24-
'http://studiov3-global-development-upgrade-equinor-web-sites-dev.c2.radix.equinor.com',
25-
'https://studio-global-development-upgrade-equinor-web-sites-dev.c2.radix.equinor.com/',
26-
]
22+
const localStudioUrl = ['http://localhost:3333']
2723
const xFrameUrls = [
2824
localUrl,
2925
...studioUrls,
30-
...studioV3Urls,
26+
...localStudioUrl,
3127
globalUrl,
3228
secretUrl,
3329
]

0 commit comments

Comments
 (0)