Skip to content

Commit

Permalink
Added TocNavigationView component
Browse files Browse the repository at this point in the history
  • Loading branch information
davidsilaghi committed Apr 29, 2020
1 parent 16a565a commit 0fcc6c8
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 12 deletions.
16 changes: 8 additions & 8 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
"@plone/volto",
"./src/addons/@plone/volto/src"
],
[
"volto-mosaic",
"./src/develop/volto-mosaic/src"
],
[
"volto-datablocks",
"./src/develop/volto-datablocks/src"
],
[
"volto-addons",
"./src/develop/volto-addons/src"
Expand Down Expand Up @@ -58,14 +66,6 @@
[
"volto-sidebar",
"./src/develop/volto-sidebar/src"
],
[
"volto-mosaic",
"./src/develop/volto-mosaic/src"
],
[
"volto-datablocks",
"./src/develop/volto-datablocks/src"
]
]
},
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export KeyFactsEdit from './Blocks/KeyFacts/KeyFactsEdit';
export KeyFactsView from './Blocks/KeyFacts/KeyFactsView';
export TocNavigationView from './theme/TocNavigationView/TocNavigationView';
export FactsheetDatabaseListing from './theme/FactsheetDatabaseListing/FactsheetDatabaseListing';
153 changes: 153 additions & 0 deletions src/components/theme/TocNavigationView/TocNavigationView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { defineMessages, injectIntl } from 'react-intl';
import React, { useState } from 'react';
import cx from 'classnames';
import {
getBlocksFieldname,
getBlocksLayoutFieldname,
getBaseUrl,
} from '@plone/volto/helpers';
import { blocks } from '~/config';
import { map } from 'lodash';
import { Grid } from 'semantic-ui-react';
import VisibilitySensor from 'react-visibility-sensor';

const messages = defineMessages({
unknownBlock: {
id: 'Unknown Block',
defaultMessage: 'Unknown Block {block}',
},
});

const splitBlocksByTOC = (blockIds, blocksContent) => {
// find position of first block id where block content is text with h2

let cursor = blockIds.findIndex((blockId, index) => {
if (blocksContent[blockId]['@type'] !== 'text') return false;

const content = blocksContent[blockId];
const blockType = content.text.blocks[0].type;
return blockType === 'header-two';
});
return [blockIds.slice(0, cursor), blockIds.slice(cursor)];
};

const extractTextKey = block => {
if (block['@type'] !== 'text') return [];

const draftBlock = block.text.blocks[0];
const { text, type, key } = draftBlock;

if (!HEADLINES.includes(type)) return [];

return [key, text];
};

const HEADLINES = ['header-two', 'header-three', 'header-four'];

let BlocksWithToc = ({ blockIds, blocksContent, intl, content, location }) => {
let [activeId, setActiveId] = useState(null);
const customSetActive = value => {
return setActiveId(value);
};
return (
<div>
<Grid>
<Grid.Column width={3}>
{map(blockIds, blockId => {
const block = blocksContent[blockId];
if (!block.text) return null;
const draftBlock = block.text.blocks[0];
const { text, type, key } = draftBlock;
if (!HEADLINES.includes(type)) return null;
return (
<a
href={`#${key}`}
className={cx(`link-${type}`, {
selected: activeId === key,
})}
>
{text}
</a>
);
})}
</Grid.Column>
<Grid.Column width={9}>
{map(blockIds, blockId => {
const Block =
blocks.blocksConfig[(blocksContent?.[blockId]?.['@type'])]?.[
'view'
] || null;
return Block !== null ? (
<VisibilitySensor>
{({ isVisible }) => {
const [textKey, text] = extractTextKey(
blocksContent[blockId],
);
if (textKey && isVisible) customSetActive(textKey);
return (
<Block
key={blockId}
id={blockId}
properties={content}
data={blocksContent[blockId]}
path={getBaseUrl(location?.pathname || '')}
/>
);
}}
</VisibilitySensor>
) : (
<div key={blockId}>
{intl.formatMessage(messages.unknownBlock, {
block: blocksContent?.[blockId]?.['@type'],
})}
</div>
);
})}
</Grid.Column>
</Grid>
</div>
);
};

BlocksWithToc = injectIntl(BlocksWithToc);

const TocNavView = ({ content, location, intl }) => {
const blocksFieldname = getBlocksFieldname(content);
const blocksLayoutFieldname = getBlocksLayoutFieldname(content);
const blockIds = content[blocksLayoutFieldname].items;
const blocksContent = content[blocksFieldname];
const [preambleIds, contentIds] = splitBlocksByTOC(blockIds, blocksContent);
return (
<div id="page-document" className="ui container">
{map(preambleIds, block => {
const Block =
blocks.blocksConfig[(content[blocksFieldname]?.[block]?.['@type'])]?.[
'view'
] || null;
return Block !== null ? (
<Block
key={block}
id={block}
properties={content}
data={content[blocksFieldname][block]}
path={getBaseUrl(location?.pathname || '')}
/>
) : (
<div key={block}>
{intl.formatMessage(messages.unknownBlock, {
block: content[blocksFieldname]?.[block]?.['@type'],
})}
</div>
);
})}
<BlocksWithToc
content={content}
blockIds={contentIds}
blocksContent={blocksContent}
location={location}
/>
</div>
);
};

export default injectIntl(TocNavView);
2 changes: 2 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { applyConfig as plotlyConfig } from 'volto-plotlycharts/config';
import { applyConfig as ckeditorConfig } from 'volto-ckeditor/config';
import { applyConfig as mosaicConfig } from 'volto-mosaic/config';
import { applyConfig as dataBlocksConfig } from 'volto-datablocks/config';
import { applyConfig as embedConfig } from 'volto-embed';
import installBise from './localconfig';

const config = [
Expand All @@ -18,6 +19,7 @@ const config = [
mosaicConfig,
dataBlocksConfig,
installBise,
embedConfig,

// draftConfig,
].reduce((acc, apply) => apply(acc), voltoConfig);
Expand Down
2 changes: 1 addition & 1 deletion src/customizations/volto/components/theme/App/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class App extends Component {
pathname={path}
/>

<Segment basic className="content-area test">
<Segment basic className="content-area">
<main>
<div className="editor-toolbar-wrapper" />
<OutdatedBrowser />
Expand Down
10 changes: 7 additions & 3 deletions src/localconfig.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// import HomepageView from '~/components/theme/HomepageView';
import FactsheetDatabaseListing from '~/components/theme/FactsheetDatabaseListing';
import codeSVG from '@plone/volto/icons/code.svg';
import { KeyFactsView, KeyFactsEdit } from './components';
import {
FactsheetDatabaseListing,
TocNavigationView,
KeyFactsView,
KeyFactsEdit,
} from './components';

const applyConfig = config => {
config.views = {
Expand All @@ -13,6 +16,7 @@ const applyConfig = config => {
layoutViews: {
...config.views.layoutViews,
factsheet_database_listing_view: FactsheetDatabaseListing,
toc_nav_view: TocNavigationView,
},
};

Expand Down

0 comments on commit 0fcc6c8

Please sign in to comment.