@plone/volto
Version:
Volto
551 lines (532 loc) • 16.8 kB
JSX
import { defineMessages } from 'react-intl';
import cloneDeep from 'lodash/cloneDeep';
import ViewTitleBlock from '@plone/volto/components/manage/Blocks/Title/View';
import ViewDescriptionBlock from '@plone/volto/components/manage/Blocks/Description/View';
import ViewToCBlock from '@plone/volto/components/manage/Blocks/ToC/View';
import ViewImageBlock from '@plone/volto/components/manage/Blocks/Image/View';
import ViewLeadImageBlock from '@plone/volto/components/manage/Blocks/LeadImage/View';
import ViewListingBlock from '@plone/volto/components/manage/Blocks/Listing/View';
import ViewVideoBlock from '@plone/volto/components/manage/Blocks/Video/View';
import ViewMapBlock from '@plone/volto/components/manage/Blocks/Maps/View';
import ViewHTMLBlock from '@plone/volto/components/manage/Blocks/HTML/View';
import EditTitleBlock from '@plone/volto/components/manage/Blocks/Title/Edit';
import EditDescriptionBlock from '@plone/volto/components/manage/Blocks/Description/Edit';
import EditToCBlock from '@plone/volto/components/manage/Blocks/ToC/Edit';
import EditImageBlock from '@plone/volto/components/manage/Blocks/Image/Edit';
import EditLeadImageBlock from '@plone/volto/components/manage/Blocks/LeadImage/Edit';
import EditListingBlock from '@plone/volto/components/manage/Blocks/Listing/Edit';
import DefaultNoResultsComponent from '@plone/volto/components/manage/Blocks/Listing/DefaultNoResultsComponent';
import GalleryNoResultsComponent from '@plone/volto/components/manage/Blocks/Listing/GalleryNoResultsComponent';
import DefaultListingBlockTemplate from '@plone/volto/components/manage/Blocks/Listing/DefaultTemplate';
import SummaryListingBlockTemplate from '@plone/volto/components/manage/Blocks/Listing/SummaryTemplate';
import EditVideoBlock from '@plone/volto/components/manage/Blocks/Video/Edit';
import EditMapBlock from '@plone/volto/components/manage/Blocks/Maps/Edit';
import EditHTMLBlock from '@plone/volto/components/manage/Blocks/HTML/Edit';
import descriptionSVG from '@plone/volto/icons/description.svg';
import titleSVG from '@plone/volto/icons/text.svg';
import cameraSVG from '@plone/volto/icons/camera.svg';
import videoSVG from '@plone/volto/icons/videocamera.svg';
import globeSVG from '@plone/volto/icons/globe.svg';
import codeSVG from '@plone/volto/icons/code.svg';
import listingBlockSVG from '@plone/volto/icons/content-listing.svg';
import tocSVG from '@plone/volto/icons/list-bullet.svg';
import searchSVG from '@plone/volto/icons/zoom.svg';
import gridSVG from '@plone/volto/icons/grid-block.svg';
import imagesSVG from '@plone/volto/icons/images.svg';
import ImageGalleryListingBlockTemplate from '@plone/volto/components/manage/Blocks/Listing/ImageGallery';
import BlockSettingsSchema from '@plone/volto/components/manage/Blocks/Block/Schema';
import ImageSettingsSchema from '@plone/volto/components/manage/Blocks/Image/LayoutSchema';
import ToCSettingsSchema from '@plone/volto/components/manage/Blocks/ToC/Schema';
import GridBlockView from '@plone/volto/components/manage/Blocks/Grid/View';
import GridBlockEdit from '@plone/volto/components/manage/Blocks/Grid/Edit';
import { GridBlockDataAdapter } from '@plone/volto/components/manage/Blocks/Grid/adapter';
import { GridBlockSchema } from '@plone/volto/components/manage/Blocks/Grid/schema';
import GridTemplates from '@plone/volto/components/manage/Blocks/Grid/templates';
import { gridTeaserDisableStylingSchema } from '@plone/volto/components/manage/Blocks/Teaser/schema';
import { gridImageDisableSizeAndPositionHandlersSchema } from '@plone/volto/components/manage/Blocks/Image/schema';
import SearchBlockView from '@plone/volto/components/manage/Blocks/Search/SearchBlockView';
import SearchBlockEdit from '@plone/volto/components/manage/Blocks/Search/SearchBlockEdit';
import RightColumnFacets from '@plone/volto/components/manage/Blocks/Search/layout/RightColumnFacets';
import LeftColumnFacets from '@plone/volto/components/manage/Blocks/Search/layout/LeftColumnFacets';
import TopSideFacets from '@plone/volto/components/manage/Blocks/Search/layout/TopSideFacets';
import {
SelectFacet,
CheckboxFacet,
DateRangeFacet,
ToggleFacet,
ToggleFacetFilterListEntry,
SelectFacetFilterListEntry,
DateRangeFacetFilterListEntry,
} from '@plone/volto/components/manage/Blocks/Search/components';
import getListingBlockAsyncData from '@plone/volto/components/manage/Blocks/Listing/getAsyncData';
import { getImageBlockSizes } from '@plone/volto/components/manage/Blocks/Image/utils';
import { getLeadImageBlockSizes } from '@plone/volto/components/manage/Blocks/LeadImage/utils';
// block sidebar schemas (not the Dexterity Layout block settings schemas)
import ListingBlockSchema from '@plone/volto/components/manage/Blocks/Listing/schema';
import SearchBlockSchema from '@plone/volto/components/manage/Blocks/Search/schema';
import VideoBlockSchema from '@plone/volto/components/manage/Blocks/Video/schema';
import ToCVariations from '@plone/volto/components/manage/Blocks/ToC/variations';
import TeaserViewBlock from '@plone/volto/components/manage/Blocks/Teaser/View';
import TeaserEditBlock from '@plone/volto/components/manage/Blocks/Teaser/Edit';
import TeaserBlockDefaultBody from '@plone/volto/components/manage/Blocks/Teaser/DefaultBody';
import { TeaserSchema } from '@plone/volto/components/manage/Blocks/Teaser/schema';
import { TeaserBlockDataAdapter } from '@plone/volto/components/manage/Blocks/Teaser/adapter';
defineMessages({
title: {
id: 'title',
defaultMessage: 'Title',
},
description: {
id: 'description',
defaultMessage: 'Description',
},
text: {
id: 'text',
defaultMessage: 'Text',
},
toc: {
id: 'toc',
defaultMessage: 'Table of Contents',
},
image: {
id: 'image',
defaultMessage: 'Image',
},
video: {
id: 'video',
defaultMessage: 'Video',
},
hero: {
id: 'hero',
defaultMessage: 'Hero',
},
table: {
id: 'table',
defaultMessage: 'Table',
},
maps: {
id: 'maps',
defaultMessage: 'Maps',
},
html: {
id: 'html',
defaultMessage: 'HTML',
},
leadimage: {
id: 'leadimage',
defaultMessage: 'Lead Image Field',
},
listing: {
id: 'listing',
defaultMessage: 'Listing',
},
// Groups
mostUsed: {
id: 'mostUsed',
defaultMessage: 'Most used',
},
media: {
id: 'media',
defaultMessage: 'Media',
},
common: {
id: 'common',
defaultMessage: 'Common',
},
// Listing block variations
summary: {
id: 'Summary',
defaultMessage: 'Summary',
},
imageGallery: {
id: 'Image gallery',
defaultMessage: 'Image gallery',
},
// Search block variations
facetsRightSide: {
id: 'Facets on right side',
defaultMessage: 'Facets on right side',
},
facetsLeftSide: {
id: 'Facets on left side',
defaultMessage: 'Facets on left side',
},
facetsTopSide: {
id: 'Facets on top',
defaultMessage: 'Facets on top',
},
selectFacet: {
id: 'selectFacet',
defaultMessage: 'Select',
},
checkboxFacet: {
id: 'checkboxFacet',
defaultMessage: 'Checkbox',
},
daterangeFacet: {
id: 'daterangeFacet',
defaultMessage: 'Date Range',
},
toggleFacet: {
id: 'toggleFacet',
defaultMessage: 'Toggle',
},
// BBB Table messages
Table: {
id: 'Table',
defaultMessage: 'Table',
},
cell: {
id: 'Cell',
defaultMessage: 'Cell',
},
insertRowBefore: {
id: 'Insert row before',
defaultMessage: 'Insert row before',
},
insertRowAfter: {
id: 'Insert row after',
defaultMessage: 'Insert row after',
},
deleteRow: {
id: 'Delete row',
defaultMessage: 'Delete row',
},
insertColBefore: {
id: 'Insert col before',
defaultMessage: 'Insert col before',
},
insertColAfter: {
id: 'Insert col after',
defaultMessage: 'Insert col after',
},
deleteCol: {
id: 'Delete col',
defaultMessage: 'Delete col',
},
fixed: {
id: 'Fixed width table cells',
defaultMessage: 'Fixed width columns',
},
compact: {
id: 'Make the table compact',
defaultMessage: 'Reduce cell padding',
},
basic: {
id: 'Reduce complexity',
defaultMessage: 'Minimalistic table design',
},
celled: {
id: 'Divide each row into separate cells',
defaultMessage: 'Add border to inner columns',
},
striped: {
id: 'Stripe alternate rows with color',
defaultMessage: 'Alternate row background color',
},
headerCell: {
id: 'Header cell',
defaultMessage: 'Header cell',
},
});
const groupBlocksOrder = [
{ id: 'mostUsed', title: 'Most used' },
{ id: 'text', title: 'Text' },
{ id: 'media', title: 'Media' },
{ id: 'common', title: 'Common' },
];
const blocksConfig = {
title: {
id: 'title',
title: 'Title',
icon: titleSVG,
group: 'text',
view: ViewTitleBlock,
edit: EditTitleBlock,
schema: BlockSettingsSchema,
restricted: ({ properties, block }) =>
properties.blocks_layout?.items?.find(
(uid) => properties.blocks?.[uid]?.['@type'] === block.id,
),
mostUsed: false,
blockHasOwnFocusManagement: true,
sidebarTab: 0,
},
description: {
id: 'description',
title: 'Description',
icon: descriptionSVG,
group: 'text',
view: ViewDescriptionBlock,
edit: EditDescriptionBlock,
schema: BlockSettingsSchema,
restricted: false,
mostUsed: false,
blockHasOwnFocusManagement: true,
sidebarTab: 0,
},
image: {
id: 'image',
title: 'Image',
icon: cameraSVG,
group: 'media',
view: ViewImageBlock,
edit: EditImageBlock,
schema: ImageSettingsSchema,
restricted: false,
mostUsed: true,
sidebarTab: 1,
getSizes: getImageBlockSizes,
},
leadimage: {
id: 'leadimage',
title: 'Lead Image Field',
icon: cameraSVG,
group: 'media',
view: ViewLeadImageBlock,
edit: EditLeadImageBlock,
schema: BlockSettingsSchema,
restricted: ({ properties }) => !properties.hasOwnProperty('image'),
mostUsed: false,
sidebarTab: 1,
getSizes: getLeadImageBlockSizes,
},
listing: {
id: 'listing',
title: 'Listing',
icon: listingBlockSVG,
group: 'common',
view: ViewListingBlock,
edit: EditListingBlock,
schema: BlockSettingsSchema,
blockSchema: ListingBlockSchema,
restricted: false,
mostUsed: true,
sidebarTab: 1,
showLinkMore: false,
noResultsComponent: DefaultNoResultsComponent,
variations: [
{
id: 'default',
isDefault: true,
title: 'Default',
template: DefaultListingBlockTemplate,
},
{
id: 'imageGallery',
title: 'Image gallery',
template: ImageGalleryListingBlockTemplate,
noResultsComponent: GalleryNoResultsComponent,
},
{
id: 'summary',
title: 'Summary',
template: SummaryListingBlockTemplate,
},
],
getAsyncData: getListingBlockAsyncData,
},
video: {
id: 'video',
title: 'Video',
icon: videoSVG,
group: 'media',
view: ViewVideoBlock,
edit: EditVideoBlock,
schema: BlockSettingsSchema,
blockSchema: VideoBlockSchema,
restricted: false,
mostUsed: true,
sidebarTab: 1,
},
toc: {
id: 'toc',
title: 'Table of Contents',
icon: tocSVG,
group: 'common',
view: ViewToCBlock,
edit: EditToCBlock,
schema: ToCSettingsSchema,
variations: ToCVariations,
restricted: false,
mostUsed: false,
sidebarTab: 1,
},
maps: {
id: 'maps',
title: 'Maps',
icon: globeSVG,
group: 'common',
view: ViewMapBlock,
edit: EditMapBlock,
schema: BlockSettingsSchema,
restricted: false,
mostUsed: false,
sidebarTab: 1,
},
html: {
id: 'html',
title: 'HTML',
icon: codeSVG,
group: 'common',
view: ViewHTMLBlock,
edit: EditHTMLBlock,
schema: BlockSettingsSchema,
restricted: false,
mostUsed: false,
sidebarTab: 0,
},
search: {
id: 'search',
title: 'Search',
icon: searchSVG,
group: 'common',
view: SearchBlockView,
edit: SearchBlockEdit,
blockSchema: SearchBlockSchema,
restricted: false,
mostUsed: false,
sidebarTab: 1,
variations: [
{
id: 'facetsRightSide',
title: 'Facets on right side',
view: RightColumnFacets,
isDefault: true,
},
{
id: 'facetsLeftSide',
title: 'Facets on left side',
view: LeftColumnFacets,
isDefault: false,
},
{
id: 'facetsTopSide',
title: 'Facets on top',
view: TopSideFacets,
isDefault: false,
},
],
extensions: {
facetWidgets: {
rewriteOptions: (name, choices) => {
return name === 'review_state'
? choices.map((opt) => ({
...opt,
label: opt.label.replace(/\[.+\]/, '').trim(),
}))
: choices;
},
types: [
{
id: 'selectFacet',
title: 'Select',
view: SelectFacet,
isDefault: true,
schemaEnhancer: SelectFacet.schemaEnhancer,
stateToValue: SelectFacet.stateToValue,
valueToQuery: SelectFacet.valueToQuery,
filterListComponent: SelectFacetFilterListEntry,
},
{
id: 'checkboxFacet',
title: 'Checkbox',
view: CheckboxFacet,
isDefault: false,
schemaEnhancer: CheckboxFacet.schemaEnhancer,
stateToValue: CheckboxFacet.stateToValue,
valueToQuery: CheckboxFacet.valueToQuery,
filterListComponent: SelectFacetFilterListEntry,
},
{
id: 'daterangeFacet',
title: 'Date Range',
view: DateRangeFacet,
isDefault: false,
stateToValue: DateRangeFacet.stateToValue,
valueToQuery: DateRangeFacet.valueToQuery,
filterListComponent: DateRangeFacetFilterListEntry,
},
{
id: 'toggleFacet',
title: 'Toggle',
view: ToggleFacet,
isDefault: false,
stateToValue: ToggleFacet.stateToValue,
valueToQuery: ToggleFacet.valueToQuery,
filterListComponent: ToggleFacetFilterListEntry,
},
],
},
},
},
// This next block is not named just grid for some reasons:
// 1.- Naming it grid will collide with the SemanticUI CSS of the Grid component
// 2.- It would prevent the transition from the old grid
// (based on @kitconcept/volto-blocks-grid) without having to perform any migration.
// This way, both can co-exist at the same time.
gridBlock: {
id: 'gridBlock',
title: 'Grid',
icon: gridSVG,
group: 'common',
view: GridBlockView,
edit: GridBlockEdit,
blockSchema: GridBlockSchema,
dataAdapter: GridBlockDataAdapter,
restricted: false,
mostUsed: true,
sidebarTab: 1,
templates: GridTemplates,
maxLength: 4,
allowedBlocks: ['image', 'listing', 'slate', 'teaser'],
},
teaser: {
id: 'teaser',
title: 'Teaser',
icon: imagesSVG,
group: 'common',
view: TeaserViewBlock,
edit: TeaserEditBlock,
restricted: false,
mostUsed: true,
sidebarTab: 1,
blockSchema: TeaserSchema,
dataAdapter: TeaserBlockDataAdapter,
variations: [
{
id: 'default',
isDefault: true,
title: 'Default',
template: TeaserBlockDefaultBody,
},
],
},
};
// This is required in order to initialize the inner blocksConfig
// for the grid block, since we need to modify how the inner teaser
// block behave in it (= no schemaEnhancer fields for teasers inside a grid)
// Afterwards, it can be further customized in add-ons using the same technique.
blocksConfig.gridBlock.blocksConfig = cloneDeep(blocksConfig);
blocksConfig.gridBlock.blocksConfig.teaser.schemaEnhancer =
gridTeaserDisableStylingSchema;
blocksConfig.gridBlock.blocksConfig.image.schemaEnhancer =
gridImageDisableSizeAndPositionHandlersSchema;
const requiredBlocks = ['title'];
const initialBlocks = {};
const initialBlocksFocus = {}; //{Document:'title'}
export function installDefaultBlocks(config) {
config.blocks.requiredBlocks = requiredBlocks;
config.blocks.blocksConfig = blocksConfig;
config.blocks.groupBlocksOrder = groupBlocksOrder;
config.blocks.initialBlocks = initialBlocks;
config.blocks.initialBlocksFocus = initialBlocksFocus;
config.blocks.showEditBlocksInBabelView = false;
}
export {
groupBlocksOrder,
requiredBlocks,
blocksConfig,
initialBlocks,
initialBlocksFocus,
};