UNPKG

@progress/sitefinity-nextjs-sdk

Version:

Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.

189 lines (188 loc) 8.14 kB
/* eslint-disable default-case */ 'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import React, { Fragment, useEffect } from 'react'; import { HeroSection } from './sections/hero-section'; import { SectionType } from './section-type'; import { NoIntentAction } from './intent-driven-content.entity'; import { useSearchParams } from 'next/navigation'; import { DGEServiceConnector } from './dynamically-generated-service-connector'; import { DG_QUERY_PARAMS } from '../shared'; import { TitleAndSummarySection } from './sections/title-and-summary'; import { FaqSection } from './sections/faq'; import { ContentItemsListSection } from './sections/content-items-list'; import { RichTextSection } from './sections/rich-text'; import { ContentItemsCardsSection } from './sections/content-items-cards'; import { ErrorSection } from './sections/error-section'; function sectionTitleByType(sectionType) { switch (sectionType) { case SectionType.TitleAndSummary: return 'Title and Summary'; case SectionType.RichText: return 'Rich Text'; case SectionType.FAQ: return 'FAQ'; case SectionType.Hero: return 'Hero'; case SectionType.ContentListCards: return 'Content List Cards'; case SectionType.ContentList: return 'Content List'; } } function renderSection(section, index, isEdit, sectionModel) { if (isEdit) { return (_jsx(Fragment, { children: _jsx("h3", { children: sectionTitleByType(section.sectionType) }, `section-title-${index}`) }, `section-edit-${index}`)); } if (!sectionModel) { return null; } switch (section.sectionType) { case SectionType.TitleAndSummary: return (_jsx(Fragment, { children: TitleAndSummarySection(sectionModel) }, `section-${index}`)); case SectionType.FAQ: return (_jsx(Fragment, { children: FaqSection(sectionModel) }, `section-${index}`)); case SectionType.Hero: return (_jsx(Fragment, { children: HeroSection(sectionModel) }, `section-${index}`)); case SectionType.ContentListCards: return (_jsx(Fragment, { children: ContentItemsCardsSection(sectionModel) }, `section-${index}`)); case SectionType.ContentList: return (_jsx(Fragment, { children: ContentItemsListSection(sectionModel) }, `section-${index}`)); case SectionType.RichText: return (_jsx(Fragment, { children: RichTextSection(sectionModel) }, `section-${index}`)); } } export function IntentDrivenContentClient(props) { const searchParams = useSearchParams(); const { defaultQuery, noIntentAction, language, siteId, pageId, sections, isEdit } = props; const skipSectionsRenderInEditMode = isEdit; const [serviceAnswer, setServiceAnswer] = React.useState({}); const [errorData, setErrorData] = React.useState(null); const responseContainsNoData = (value) => { if (value == null) { return true; } if (Array.isArray(value)) { return value.length === 0; } if (typeof value === 'object' && Object.keys(value).length === 0) { return true; } if (typeof value === 'string') { return value.includes('Not enough data'); } return false; }; function getUserJourney() { const userJourneyData = { currentUserJourney: [], subjectKey: '', source: '' }; if (window.DataIntelligenceSubmitScript) { userJourneyData.currentUserJourney = window.DataIntelligenceSubmitScript?._client?.recommenderClient?.getClientJourney() || []; userJourneyData.subjectKey = window.DataIntelligenceSubmitScript?._client?.subjectKey || ''; userJourneyData.source = window.DataIntelligenceSubmitScript?._client?.source || ''; } return userJourneyData; } const sendDataToInsight = (query) => { if (window.DataIntelligenceSubmitScript) { window.DataIntelligenceSubmitScript?._client?.sentenceClient?.writeSentence({ predicate: 'Intent Box Prompt', object: query }); } }; const loadContent = async () => { const query = searchParams.get(DG_QUERY_PARAMS.query) || (noIntentAction === NoIntentAction.GenerateWithPredefinedQuery ? defaultQuery : undefined); const variationId = searchParams.get(DG_QUERY_PARAMS.variationId) || undefined; if (Object.keys(serviceAnswer).length > 0) { setServiceAnswer({}); } if (errorData) { setErrorData(null); } if (!query && !variationId) { return; } const sectionsToQuery = sections?.filter(x => x?.sectionType) .map(s => s.sectionType?.includes('_') ? s.sectionType.split('_')[0] : s.sectionType) .filter(x => x); // If no sections are configured, do not send a request if (!sectionsToQuery?.length) { return; } setServiceAnswer(Object.fromEntries(sectionsToQuery.map(sectionType => [sectionType, { isLoading: true, sectionData: null }]))); const isUserQuery = !!searchParams.get(DG_QUERY_PARAMS.query); if (isUserQuery) { sendDataToInsight(query); } const userJourneyData = getUserJourney(); DGEServiceConnector.fetchDataStream({ sections: sectionsToQuery, query, siteId, language, pageId, isUserQuery, variationId, userJourneyData }, (data) => { setServiceAnswer(prev => ({ ...prev, [data.sectionName]: { isLoading: false, sectionData: data.sectionData } })); }, (error) => { setErrorData(error); setServiceAnswer(prev => { const updated = { ...prev }; Object.keys(updated).forEach(key => { updated[key] = { isLoading: false, sectionData: null }; }); return updated; }); }, (collectedServiceData) => { const dataArray = Array.isArray(collectedServiceData) ? collectedServiceData : []; const hasNoData = dataArray.length === 0 || dataArray.every(item => responseContainsNoData(item?.sectionData)); if (hasNoData) { setErrorData({ errorMessage: 'No data for this query could be found. Try another one.', errorType: 'NoContent' }); setServiceAnswer(prev => { const updated = { ...prev }; Object.keys(updated).forEach(key => { updated[key] = { isLoading: false, sectionData: null }; }); return updated; }); return; } setServiceAnswer(prev => { const updatedData = { ...prev }; dataArray.forEach(dataItem => { updatedData[dataItem.sectionName] = { isLoading: false, sectionData: dataItem.sectionData }; }); return updatedData; }); }); }; useEffect(() => { !isEdit && loadContent(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchParams]); if (errorData) { return [ _jsx(Fragment, { children: ErrorSection({ isLoading: false, sectionData: errorData, cssClassName: '' }) }, "section-error") ]; } return sections.map((section, index) => { const sectionType = section.sectionType?.includes('_') ? section.sectionType.split('_')[0] : section.sectionType; if (!sectionType) { return null; } const sectionModel = { ...serviceAnswer?.[sectionType], cssClassName: section.cssClassName }; return renderSection(section, index, skipSectionsRenderInEditMode, sectionModel); }); }