diff --git a/packages/volto-slate-glossary/src/components/Tooltips.jsx b/packages/volto-slate-glossary/src/components/Tooltips.jsx index 5c13c4c..0c39260 100644 --- a/packages/volto-slate-glossary/src/components/Tooltips.jsx +++ b/packages/volto-slate-glossary/src/components/Tooltips.jsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import jwtDecode from 'jwt-decode'; -import { atom, useSetAtom } from 'jotai'; +import { useSetAtom } from 'jotai'; import _ from 'lodash'; import { Text } from 'slate'; import { v5 as uuidv5 } from 'uuid'; @@ -9,23 +9,11 @@ import { Popup } from 'semantic-ui-react'; import { getUser } from '@plone/volto/actions'; import { getTooltipTerms } from '../actions'; import { MY_NAMESPACE } from '../utils'; +import { tooltippedTextsAtom } from '../utils'; import config from '@plone/volto/registry'; -// jotai store for tooltip enhanced slate leafs -export const tooltippedTextsAtom = atom({}); - -const Tooltips = () => { - return ( - <> - - - - ); -}; - -const Fetch = () => { +export const FetchTooltipTerms = ({ token }) => { const dispatch = useDispatch(); - const token = useSelector((state) => state.userSession?.token); useEffect(() => { dispatch(getTooltipTerms()); @@ -41,23 +29,36 @@ const Fetch = () => { return
; }; -const CalculateTexts = () => { +const Tooltips = (props) => { + return ( + <> + + + ); +}; + +const CalculateTexts = ({ pathname }) => { const glossaryterms = useSelector( (state) => state.glossarytooltipterms?.result?.items, ); const blocks_layout = useSelector( - (state) => state.content.data?.blocks_layout, + (state) => state.content?.data?.blocks_layout, ); - const blocks = useSelector((state) => state.content.data?.blocks); + const blocks = useSelector((state) => state.content?.data?.blocks); + + // We can't use atom Family as pathname is not known here. const setTooltippedTexts = useSetAtom(tooltippedTextsAtom); useEffect(() => { if (glossaryterms) { let texts = calculateTexts(blocks, blocks_layout, glossaryterms); - // Update jotai atom - setTooltippedTexts(texts); + // Store texts and pathname in atom + setTooltippedTexts({ pathname: pathname, texts: texts }); + // return () => { + // setTooltippedTexts({ pathname: undefined, texts: [] }); + // }; } - }, [blocks, blocks_layout, glossaryterms, setTooltippedTexts]); + }, [blocks, blocks_layout, glossaryterms, pathname, setTooltippedTexts]); return
; }; @@ -238,6 +239,9 @@ const calculateTexts = (blocks, blocks_layout, glossaryterms) => { return; } let key = uuidv5(str, MY_NAMESPACE); + if (Object.keys(result).includes(key)) { + return; + } let [value, newTerms] = enhanceTextWithTooltips( str, remainingGlossaryterms, diff --git a/packages/volto-slate-glossary/src/components/__snapshots__/Tooltips.test.js.snap b/packages/volto-slate-glossary/src/components/__snapshots__/Tooltips.test.js.snap index cb2c9a3..e85156c 100644 --- a/packages/volto-slate-glossary/src/components/__snapshots__/Tooltips.test.js.snap +++ b/packages/volto-slate-glossary/src/components/__snapshots__/Tooltips.test.js.snap @@ -120,9 +120,6 @@ exports[`Tooltips are generated for all occurrences 1`] = ` id="Portal" /> -
@@ -226,9 +223,6 @@ exports[`Tooltips are generated only case sensitive 1`] = ` id="Portal" />
-
@@ -337,9 +331,6 @@ exports[`Tooltips are generated only for first occurrences per page 1`] = ` id="Portal" />
-
@@ -424,9 +415,6 @@ exports[`Tooltips divers – NO tooltips if route doesn't match configuration 1 exports[`Tooltips divers – component Tooltips is rendered in AppExtras 1`] = `
-
diff --git a/packages/volto-slate-glossary/src/index.js b/packages/volto-slate-glossary/src/index.js index 3220dab..6568c9d 100644 --- a/packages/volto-slate-glossary/src/index.js +++ b/packages/volto-slate-glossary/src/index.js @@ -2,6 +2,7 @@ import GlossaryView from './components/GlossaryView'; import TermView from './components/TermView'; import { glossarytermsReducer, glossarytooltiptermsReducer } from './reducers'; import { TextWithGlossaryTooltips } from './utils'; +import { FetchTooltipTerms } from './components/Tooltips'; const applyConfig = (config) => { config.settings.glossary = { @@ -13,6 +14,14 @@ const applyConfig = (config) => { text: ({ children }) => , }; + config.settings.appExtras = [ + ...config.settings.appExtras, + { + match: '/', + component: FetchTooltipTerms, + }, + ]; + config.views = { ...config.views, contentTypesViews: { diff --git a/packages/volto-slate-glossary/src/utils.js b/packages/volto-slate-glossary/src/utils.js index 5214203..6b66f00 100644 --- a/packages/volto-slate-glossary/src/utils.js +++ b/packages/volto-slate-glossary/src/utils.js @@ -1,29 +1,41 @@ import { useSelector } from 'react-redux'; import { v5 as uuidv5 } from 'uuid'; -import { useAtomValue } from 'jotai'; -import { tooltippedTextsAtom } from './components/Tooltips'; +import { atom, useAtomValue } from 'jotai'; + +// Jotai store for tooltip enhanced slate leafs +export const tooltippedTextsAtom = atom({ pathname: undefined, texts: [] }); export const MY_NAMESPACE = '4549d0a3-5fc2-4a94-bf96-eb7ddf5363a4'; export const TextWithGlossaryTooltips = ({ text }) => { - // Read jotai atom and return value with the appropriate key. + const { pathname } = useSelector((state) => state.router?.location); + + // Read Jotai atom and return value with the appropriate key. const tooltippedTexts = useAtomValue(tooltippedTextsAtom); - const location = useSelector((state) => state.router?.location); + const currentuser = useSelector((state) => state.users?.user); + + /** + * Skip enhancing with tooltip markup for some conditions + */ + + // No tooltips if pathname is not configured to have tooltips + if (!tooltippedTexts?.pathname || tooltippedTexts?.pathname !== pathname) { + return text; + } // No tooltips if user opted out - const currentuser = useSelector((state) => state.users?.user); const showGlossarytooltipsUser = currentuser?.glossarytooltips ?? true; if (!showGlossarytooltipsUser) { return text; } // No tooltips on home page, in edit mode, and add mode - if (location === undefined) { + if (pathname === undefined) { return text; } - const isEditMode = location.pathname.slice(-5) === '/edit'; - if (isEditMode || location.pathname === '/' || !__CLIENT__) { + const isEditMode = pathname.slice(-5) === '/edit'; + if (isEditMode || pathname === '/' || !__CLIENT__) { return text; } @@ -37,6 +49,9 @@ export const TextWithGlossaryTooltips = ({ text }) => { return text; } let uid = uuidv5(text, MY_NAMESPACE); - // No match in store if this route is not configured for tooltips. Return text unchanged. - return tooltippedTexts[uid] ? tooltippedTexts[uid] : text; + // No match in store if this location is not configured for tooltips. Return text unchanged. + const newText = Object.keys(tooltippedTexts?.texts).includes(uid) + ? tooltippedTexts.texts[uid] + : text; + return newText; };