diff --git a/.release-it.json b/.release-it.json index 42260c9..71d890c 100644 --- a/.release-it.json +++ b/.release-it.json @@ -1,17 +1,18 @@ { - "github": { - "release": true + "npm": { + "publish": true }, "git": { - "commitMessage": "chore: release ${version}" + "changelog": "npx auto-changelog --stdout --commit-limit false -u --template https://raw.githubusercontent.com/release-it/release-it/master/templates/changelog-compact.hbs", + "tagName": "${version}" + }, + "github": { + "release": true, + "releaseName": "${version}", + "releaseNotes": "npx auto-changelog --stdout --commit-limit false -u --template https://raw.githubusercontent.com/release-it/release-it/master/templates/changelog-compact.hbs" }, - "plugins": { - "@release-it/conventional-changelog": { - "infile": "CHANGELOG.md", - "header": "# Changelog", - "preset": { - "name": "conventionalcommits" - } - } + "hooks": { + "before:init": "", + "after:bump": "npx auto-changelog --commit-limit false -p" } -} +} \ No newline at end of file diff --git a/README.md b/README.md index 40036a5..20801ab 100644 --- a/README.md +++ b/README.md @@ -4,25 +4,31 @@ Volto Add-On `@rohberg/volto-slate-glossary` adds tooltips for glossary terms of ![Tooltips @rohberg/volto-slate-glossary](https://github.com/rohberg/volto-slate-glossary/raw/main/public/volto-slate-glossary-tooltips.png) -Determine where to apply tooltips in your project by match configuration: - import { Tooltips } from '@rohberg/volto-slate-glossary/components'; +Install Plone Add-On [collective.glossary](https://github.com/collective/collective.glossary) in your backend. - export default function applyConfig(config) { - config.settings.appExtras = [ - ...config.settings.appExtras, - { - match: '/documentation', - component: Tooltips, - }, - { - match: '/news', - component: Tooltips, - }, - ]; - return config; - } +Determine where to apply tooltips in your project by match configuration: + +```javascript +import { Tooltips } from '@rohberg/volto-slate-glossary/components'; + +export default function applyConfig(config) { + config.settings.appExtras = [ + ...config.settings.appExtras, + { + match: '/documentation', + component: Tooltips, + }, + { + match: '/news', + component: Tooltips, + }, + ]; + + return config; +} +``` By default we show a tooltip when a word matches case insensitively: when the term is "Hello" or "hello", a tooltip is shown for "Hello", "hello", "HELLO", "hElLo", etcetera. @@ -34,11 +40,21 @@ config.settings.glossary.caseSensitive = true; Regardless of this setting, when you have a fully uppercase term, for example `REST` (Representational State Transfer), always only the exact word `REST` gets a tooltip, not `rest` or `Rest`. -Install Plone Add-On [collective.glossary](https://github.com/collective/collective.glossary) in your backend. +By default we show tooltips for all occurences of a term. + +Since version 2.0.0 you can configure to only show tooltips for the first occurence on a page. +```js +config.settings.glossary.matchOnlyFirstOccurence = true; +``` User can opt-out by setting glossarytooltips to false. Add a boolean member field *glossarytooltips* for it. -This add-on requires Volto with Slate editor. Be sure to upgrade to Volto >= 16.0.0-alpha.15. +## Compatibility + +| volto-slate-glossary version | Volto version | +|-------------|---------------| +| 1.x.x | >= Volto 16.0.0-alpha.15 | +| 2.x.x | >= Volto 18.0.0-alpha.48 | diff --git a/package.json b/package.json index 2d6acc0..a5ee65e 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,27 @@ "version": "1.0.3", "description": "Add tooltips for glossary terms", "main": "src/index.js", + "author": "Katja Süss, https://github.com/rohberg", "license": "MIT", + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "homepage": "https://github.com/rohberg/volto-slate-glossary", "keywords": [ "volto-addon", "volto", "plone", - "react" + "react", + "glossary" ], + "repository": { + "type": "git", + "url": "git@github.com:rohberg/volto-slate-glossary.git" + }, + "bugs": { + "url": "https://github.com/rohberg/volto-slate-glossary/issues" + }, "scripts": { "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon", "release": "release-it" @@ -18,10 +32,6 @@ "dependencies": { "@plone/scripts": "*" }, - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org/" - }, "devDependencies": { "@release-it/conventional-changelog": "^8.0.2", "release-it": "^17.6.0" diff --git a/src/components/glossarytooltips.less b/src/components/glossarytooltips.less index f0ff612..5c195b6 100644 --- a/src/components/glossarytooltips.less +++ b/src/components/glossarytooltips.less @@ -1,29 +1,28 @@ .glossarytooltip { - cursor: help; - border-bottom: 2px dotted #963c38; + cursor: help; + border-bottom: 2px dotted #963c38; } .ui.popup { - hyphens: auto; - font-size: 75% !important; - ol { - padding-left: 1rem; - } + hyphens: auto; + font-size: 75% !important; + ol { + padding-left: 1rem; + } } .hidden-helper { - display: none; + display: none; } - // Glossar .glossary h2.letter { - background: #963c38; - color: white; - margin: 2rem 0 1rem; - padding: 0.3em .5em; + background: #963c38; + color: white; + margin: 2rem 0 1rem; + padding: 0.3em 0.5em; } .term h3 { - span { - font-size: 80%; - } -} \ No newline at end of file + span { + font-size: 80%; + } +} diff --git a/src/index.js b/src/index.js index a3be431..ba4f81e 100644 --- a/src/index.js +++ b/src/index.js @@ -3,13 +3,18 @@ import TermView from './components/TermView'; import { glossarytermsReducer, glossarytooltiptermsReducer } from './reducers'; import { TextWithGlossaryTooltips } from './utils'; -export default (config) => { +const applyConfig = (config) => { config.settings.glossary = { caseSensitive: false, + matchOnlyFirstOccurence: false, }; + + config.views.viewContext['volto-slate-glossary'] = []; + config.settings.slate.leafs = { text: ({ children }) => , }; + config.views = { ...config.views, contentTypesViews: { @@ -27,3 +32,5 @@ export default (config) => { return config; }; + +export default applyConfig; diff --git a/src/utils.js b/src/utils.js index 5fde20a..7b2778a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,10 +1,10 @@ import React from 'react'; -import config from '@plone/volto/registry'; import { useSelector } from 'react-redux'; import { flatten } from 'lodash'; import { Popup } from 'semantic-ui-react'; import { useLocation } from 'react-router-dom'; - +import { useViewContext } from '@plone/volto/components/theme/View/View'; +import config from '@plone/volto/registry'; /** * import from @plone/volto-slate Leaf when ready there @@ -36,17 +36,22 @@ const applyLineBreakSupport = (children) => { export const TextWithGlossaryTooltips = ({ text }) => { const caseSensitive = config.settings.glossary.caseSensitive; + const matchOnlyFirstOccurence = + config.settings.glossary.matchOnlyFirstOccurence; const glossaryterms = useSelector( (state) => state.glossarytooltipterms?.result?.items, ); const location = useLocation(); - // no tooltips if user opted out + let matchedGlossaryTerms = useViewContext('volto-slate-glossary'); + + // No tooltips if user opted out const currentuser = useSelector((state) => state.users?.user); const glossarytooltips = currentuser?.glossarytooltips ?? true; if (!glossarytooltips) { return text; } + // No tooltips in edit and add mode const isEditMode = location.pathname.slice(-5) === '/edit'; const isAddMode = location.pathname.slice(-4) === '/add'; if (isEditMode || isAddMode || location.pathname === '/' || !__CLIENT__) { @@ -55,7 +60,12 @@ export const TextWithGlossaryTooltips = ({ text }) => { let result = [{ type: 'text', val: text }]; if (glossaryterms !== undefined) { - glossaryterms.forEach((term) => { + let remainingGlossaryterms = matchOnlyFirstOccurence + ? glossaryterms.filter( + (term) => !matchedGlossaryTerms.includes(term.term), + ) + : glossaryterms; + remainingGlossaryterms.forEach((term) => { result = result.map((chunk) => { if (chunk.type === 'text') { let new_chunk = []; @@ -68,21 +78,32 @@ export const TextWithGlossaryTooltips = ({ text }) => { let myre = `(? 0) { - new_chunk.push({ type: 'text', val: chunk_val.slice(index, res.index) }); + new_chunk.push({ + type: 'text', + val: chunk_val.slice(index, res.index), + }); } new_chunk.push({ type: 'glossarytermtooltip', @@ -103,7 +124,9 @@ export const TextWithGlossaryTooltips = ({ text }) => { if (el.type === 'text') { return applyLineBreakSupport(el.val); } else { - let idx = glossaryterms.findIndex((variant) => variant.term.toLowerCase() === el.val.toLowerCase()); + let idx = glossaryterms.findIndex( + (variant) => variant.term.toLowerCase() === el.val.toLowerCase(), + ); let definition = glossaryterms[idx]?.definition || ''; switch (definition.length) { case 0: