Skip to content

Commit

Permalink
use summary component in listings and teaser
Browse files Browse the repository at this point in the history
  • Loading branch information
davisagli committed Jan 29, 2025
1 parent e523b8d commit a23e6c0
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 49 deletions.
4 changes: 2 additions & 2 deletions packages/volto-light-theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
},
"dependencies": {
"@plone/components": "workspace:^",
"uuid": "^11.0.0",
"react-aria-components": "^1.5.0",
"react-colorful": "^5.6.1"
"react-colorful": "^5.6.1",
"uuid": "^11.0.0"
},
"peerDependencies": {
"@eeacms/volto-accordion-block": "^10.4.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// See Customization for more info
import React from 'react';
import PropTypes from 'prop-types';
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';

import { isInternalURL } from '@plone/volto/helpers/Url/Url';
import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers/Url/Url';
import config from '@plone/volto/registry';
import DefaultSummary from '@kitconcept/volto-light-theme/components/Summary/DefaultSummary';

const DefaultTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
let link = null;
Expand All @@ -24,16 +23,22 @@ const DefaultTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
return (
<>
<div className="items">
{items.map((item) => (
<div className="listing-item" key={item['@id']}>
<ConditionalLink item={item} condition={!isEditMode}>
<div className="listing-body">
<h2>{item.title ? item.title : item.id}</h2>
<p>{item.description}</p>
</div>
</ConditionalLink>
</div>
))}
{items.map((item) => {
const Summary =
config.getComponent({
name: 'Summary',
dependencies: [item['@type']],
}).component || DefaultSummary;
return (
<div className="listing-item" key={item['@id']}>
<ConditionalLink item={item} condition={!isEditMode}>
<div className="listing-body">
<Summary item={item} HeadingTag="h2" />
</div>
</ConditionalLink>
</div>
);
})}
</div>

{link && <div className="footer">{link}</div>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
import Component from '@plone/volto/components/theme/Component/Component';
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';

import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers/Url/Url';
import config from '@plone/volto/registry';

import { isInternalURL } from '@plone/volto/helpers/Url/Url';
import DefaultSummary from '@kitconcept/volto-light-theme/components/Summary/DefaultSummary';

const GridTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
let link = null;
Expand All @@ -27,11 +25,15 @@ const GridTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
<div className="items">
{items.map((item) => {
const ItemBodyTemplate = () => {
const hasType = item['@type'];
const CustomItemBodyTemplate = config.getComponent({
name: 'GridListingItemTemplate',
dependencies: [hasType],
dependencies: [item['@type']],
}).component;
const Summary =
config.getComponent({
name: 'Summary',
dependencies: [item['@type']],
}).component || DefaultSummary;

return CustomItemBodyTemplate ? (
<CustomItemBodyTemplate item={item} />
Expand All @@ -47,12 +49,7 @@ const GridTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
)}
<div className="item">
<div className="content">
{item?.head_title && (
<div className="headline">{item.head_title}</div>
)}

<h2>{item?.title}</h2>
{!item.hide_description && <p>{item?.description}</p>}
<Summary item={item} HeadingTag="h2" />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
import Component from '@plone/volto/components/theme/Component/Component';
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers/Url/Url';
import config from '@plone/volto/registry';

import { isInternalURL } from '@plone/volto/helpers/Url/Url';
import DefaultSummary from '@kitconcept/volto-light-theme/components/Summary/DefaultSummary';

const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
let link = null;
Expand All @@ -25,11 +24,15 @@ const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
<>
<div className="items">
{items.map((item) => {
const hasType = item['@type'];
const CustomItemBodyTemplate = config.getComponent({
name: 'SummaryListingItemTemplate',
dependencies: [hasType],
dependencies: [item['@type']],
}).component;
const Summary =
config.getComponent({
name: 'Summary',
dependencies: [item['@type']],
}).component || DefaultSummary;

const ItemBodyTemplate = () =>
CustomItemBodyTemplate ? (
Expand All @@ -38,8 +41,7 @@ const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
<>
<Component componentName="PreviewImage" item={item} alt="" />
<div className="listing-body">
<h3>{item.title ? item.title : item.id}</h3>
<p>{item.description}</p>
<Summary item={item} HeadingTag="h3" />
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Message } from 'semantic-ui-react';
import { defineMessages, useIntl } from 'react-intl';
import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
import { isInternalURL } from '@plone/volto/helpers/Url/Url';
import MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
import cx from 'classnames';
import config from '@plone/volto/registry';
import DefaultSummary from '@kitconcept/volto-light-theme/components/Summary/DefaultSummary';

const messages = defineMessages({
PleaseChooseContent: {
id: 'Please choose an existing content as source for this element',
defaultMessage:
'Please choose an existing content as source for this element',
},
});

const TeaserDefaultTemplate = (props) => {
const { className, data, isEditMode, style } = props;
const intl = useIntl();
const href = data.href?.[0];
const image = data.preview_image?.[0];
const url = data.preview_image?.[0]?.['@id'];

const Image = config.getComponent('Image').component;
const Summary =
config.getComponent({
name: 'Summary',
dependencies: [data['@type']],
}).component || DefaultSummary;
const { openExternalLinkInNewTab } = config.settings;

return (
<div className={cx('block teaser', className)} style={style}>
<>
{!href && isEditMode && (
<Message>
<div className="teaser-item placeholder">
<img src={imageBlockSVG} alt="" />
<p>{intl.formatMessage(messages.PleaseChooseContent)}</p>
</div>
</Message>
)}
{href && (
<MaybeWrap
condition={!isEditMode}
as={UniversalLink}
href={href['@id']}
target={
data.openLinkInNewTab ||
(openExternalLinkInNewTab && !isInternalURL(href['@id']))
? '_blank'
: null
}
>
<div className="teaser-item default">
{url && !image?.image_field ? (
<div className="image-wrapper">
<Image src={url} alt="" loading="lazy" responsive={true} />
</div>
) : (
(href.hasPreviewImage || href.image_field || image) && (
<div className="image-wrapper">
<Image
item={image || href}
imageField={image ? image.image_field : href.image_field}
alt=""
loading="lazy"
responsive={true}
/>
</div>
)
)}
<div className="content">
<Summary item={data} HeadingTag="h2" />
</div>
</div>
</MaybeWrap>
)}
</>
</div>
);
};

TeaserDefaultTemplate.propTypes = {
data: PropTypes.objectOf(PropTypes.any).isRequired,
isEditMode: PropTypes.bool,
};

export default TeaserDefaultTemplate;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const DefaultSummary = (props) => {
const { item, HeadingTag = 'h3' } = props;
return (
<>
{item?.head_title && <div className="headline">{item.head_title}</div>}
<HeadingTag className="title">
{item.title ? item.title : item.id}
</HeadingTag>
{!item.hide_description && (
<p className="description">{item.description}</p>
)}
</>
);
};

export default DefaultSummary;
34 changes: 34 additions & 0 deletions packages/volto-light-theme/src/components/Summary/EventSummary.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const EventSummary = (props) => {
const { item, HeadingTag = 'h3' } = props;
const formatter = new Intl.DateTimeFormat(item.Language || 'default', {
year: 'numeric',
month: 'long',
day: 'numeric',
});

let kicker = [
item.start && item.end && (
<span className="day" key="day" suppressHydrationWarning>
{formatter.formatRange(new Date(item.start), new Date(item.end))}
</span>
),
item.head_title,
].filter((x) => x);
if (kicker.length > 1) {
kicker = kicker.reduce((prev, curr) => [prev, ' | ', curr]);
}

return (
<>
{kicker.length ? <div className="headline">{kicker}</div> : null}
<HeadingTag className="title">
{item.title ? item.title : item.id}
</HeadingTag>
{!item.hide_description && (
<p className="description">{item.description}</p>
)}
</>
);
};

export default EventSummary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const NewsItemSummary = (props) => {
const { item, HeadingTag = 'h3' } = props;
const formatter = new Intl.DateTimeFormat(item.Language || 'default', {
year: 'numeric',
month: 'long',
day: 'numeric',
});

let kicker = [
item.EffectiveDate !== 'None' && item.effective && (
<span className="day" key="day" suppressHydrationWarning>
{formatter.format(new Date(item.effective))}
</span>
),
item.head_title,
].filter((x) => x);
if (kicker.length > 1) {
kicker = kicker.reduce((prev, curr) => [prev, ' | ', curr]);
}

return (
<>
{kicker.length ? <div className="headline">{kicker}</div> : null}
<HeadingTag className="title">
{item.title ? item.title : item.id}
</HeadingTag>
{!item.hide_description && (
<p className="description">{item.description}</p>
)}
</>
);
};

export default NewsItemSummary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* OVERRIDE DefaultBody.jsx
* REASON: Look up Summary component.
*/

import DefaultBody from '../../../../../../components/Blocks/Teaser/DefaultBody';

export default DefaultBody;
14 changes: 14 additions & 0 deletions packages/volto-light-theme/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import installSlots from './config/slots';

import '@plone/components/dist/basic.css';
import type { BlocksData } from '@plone/types';
import NewsItemSummary from './components/Summary/NewsItemSummary';
import EventSummary from './components/Summary/EventSummary';

defineMessages({
Press: {
Expand Down Expand Up @@ -48,6 +50,18 @@ const applyConfig = (config: ConfigType) => {
component: Container,
});

// Register content type Summary components
config.registerComponent({
name: 'Summary',
component: NewsItemSummary,
dependencies: ['News Item'],
});
config.registerComponent({
name: 'Summary',
component: EventSummary,
dependencies: ['Event'],
});

config.registerUtility({
name: 'migrateToVLT6ColorAndWidthModel',
type: 'transform',
Expand Down
Loading

0 comments on commit a23e6c0

Please sign in to comment.