UNPKG

design-comuni-plone-theme

Version:
208 lines (195 loc) 6.01 kB
/** * Diff field component. * @module components/manage/Diff/DiffField */ /* CUSTOMIZATIONS - Overhaul all logic and html, use something that actually does the job - Still need to test dates, images not being shown correctly, might revert to filename if the solution to this bug is not quick and easy - Backend has to fix history, RelList fields not appearing in response */ import React, { useMemo } from 'react'; import { isEqual } from 'lodash'; import PropTypes from 'prop-types'; import { Table } from 'semantic-ui-react'; import { useSelector } from 'react-redux'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { blockIsNotEmptyPlaceholder, SSRRenderHtml, } from 'design-comuni-plone-theme/helpers'; /** * Enhanced diff words utility * @function diffWords * @param oneStr Field one * @param twoStr Field two */ const readable_date_format = { dateStyle: 'full', timeStyle: 'short', }; const booleanMapping = { true: 'Si', false: 'No', }; /** * Diff field component. * @function DiffField * @param {*} one Field one * @param {*} two Field two * @param {Object} schema Field schema * @returns {string} Markup of the component. */ const DiffField = ({ one, two, contentOne, contentTwo, view, schema, diffLib, htmlDiffLib, field, store, history, }) => { const language = useSelector((state) => state.intl.locale); const diff2 = (prev, curr) => htmlDiffLib.default.execute( prev ? String(prev) : '', curr ? String(curr) : '', ); const diffs = useMemo(() => { let parts; if (isEqual(one, two) || field === 'blocks_layout') return null; if (schema?.widget) { switch (schema.widget) { case 'richtext': parts = diff2(one?.data, two?.data); break; case 'datetime': parts = diff2( new Intl.DateTimeFormat(language, readable_date_format).format( new Date(one), ), new Intl.DateTimeFormat(language, readable_date_format).format( new Date(two), ), ); break; case 'blocks': if ( (!blockIsNotEmptyPlaceholder(one) && !blockIsNotEmptyPlaceholder(two)) || !!!store ) break; const first = SSRRenderHtml(history, store, one, schema.widget); const second = SSRRenderHtml(history, store, two, schema.widget); parts = diff2(first, second); break; case 'json': if (isEqual(contentOne, contentTwo)) break; const bOne = SSRRenderHtml(history, store, contentOne, schema.widget); const bTwo = SSRRenderHtml(history, store, contentTwo, schema.widget); parts = diff2(bOne, bTwo); break; default: parts = diff2(one, two); break; } } else if (schema.type === 'object' && store) { if (field.includes('image') && isEqual(one?.filename, two?.filename)) return; const first = SSRRenderHtml(history, store, one, field); const second = SSRRenderHtml(history, store, two, field); parts = diff2(first, second); } else if (schema.type === 'array') { const oneArray = (one || []).map((i) => i?.title || i).join(', '); const twoArray = (two || []).map((j) => j?.title || j).join(', '); parts = diff2(oneArray, twoArray); } else if ( schema?.type === 'boolean' && !isEqual(booleanMapping[!!one], booleanMapping[!!two]) ) { parts = diff2(booleanMapping[!!one], booleanMapping[!!two]); } else { parts = diff2(one, two); } return parts; // eslint-disable-next-line react-hooks/exhaustive-deps }, [one, two, schema, field, language, store, history]); return store && diffs ? ( <Table compact data-testid="DiffField" className="diffField"> <Table.Header> <Table.Row> <Table.HeaderCell colSpan={2}>{schema.title}</Table.HeaderCell> </Table.Row> </Table.Header> <Table.Body> {view === 'split' && ( <Table.Row> <Table.Cell width={8} verticalAlign="top"> <div className="previous-state" dangerouslySetInnerHTML={{ __html: SSRRenderHtml( history, store, schema?.type === 'boolean' ? booleanMapping[!!one] : schema?.widget === 'json' ? contentOne : one, schema?.widget ?? (schema?.type === 'object' && field.includes('image') ? field : schema?.type), ), }} /> </Table.Cell> <Table.Cell width={8} verticalAlign="top"> <div className="current-state" dangerouslySetInnerHTML={{ __html: diffs, }} /> </Table.Cell> </Table.Row> )} {view === 'unified' && ( <Table.Row> <Table.Cell width={16} verticalAlign="top"> <div className="current-state" dangerouslySetInnerHTML={{ __html: diffs, }} /> </Table.Cell> </Table.Row> )} </Table.Body> </Table> ) : null; }; /** * Property types. * @property {Object} propTypes Property types. * @static */ DiffField.propTypes = { one: PropTypes.any.isRequired, two: PropTypes.any.isRequired, contentOne: PropTypes.any, contentTwo: PropTypes.any, view: PropTypes.string.isRequired, schema: PropTypes.shape({ widget: PropTypes.string, type: PropTypes.string, title: PropTypes.string, }).isRequired, }; export default injectLazyLibs(['htmlDiffLib'])(DiffField);