From 00e641f039399ecab52f2802cb227fa22af66522 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 13:14:42 +0100 Subject: [PATCH 01/10] Use function-as-child-component pattern for hover actions buttons --- .../components/card/article/ArticleBody.tsx | 43 ++++--- .../components/card/snapLink/SnapLinkCard.tsx | 42 ++++--- .../src/components/feed/FeedItem.tsx | 30 +++-- .../inputs/HoverActionButtonWrapper.tsx | 108 ++++++------------ .../components/inputs/HoverActionButtons.tsx | 41 ++++--- .../inputs/__tests__/HoverActions.spec.tsx | 61 ++++++---- 6 files changed, 170 insertions(+), 155 deletions(-) diff --git a/fronts-client/src/components/card/article/ArticleBody.tsx b/fronts-client/src/components/card/article/ArticleBody.tsx index 9c66dd2e877..a53213286dd 100644 --- a/fronts-client/src/components/card/article/ArticleBody.tsx +++ b/fronts-client/src/components/card/article/ArticleBody.tsx @@ -106,7 +106,7 @@ interface ArticleBodyProps { sectionName?: string; displayPlaceholders?: boolean; uuid: string; - onDelete?: () => void; + onDelete: () => void; onAddToClipboard?: () => void; isUneditable?: boolean; byline?: string; @@ -321,22 +321,35 @@ const articleBodyDefault = React.memo( + toolTipAlign={'right'} + > + {(props) => ( + <> + + + {onAddToClipboard && ( + + )} + + + )} + ); diff --git a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx index 1a24e8cda48..7b047d68578 100644 --- a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx +++ b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx @@ -54,8 +54,8 @@ const SnapLinkURL = styled.p` interface ContainerProps { onDragStart?: (d: React.DragEvent) => void; onDrop?: (d: React.DragEvent) => void; - onDelete?: (uuid: string) => void; - onAddToClipboard?: (uuid: string) => void; + onDelete: () => void; + onAddToClipboard: () => void; onClick?: () => void; id: string; collectionId?: string; @@ -192,23 +192,33 @@ const SnapLinkCard = ({ justify={'space-between'} > + > + {(props) => ( + <> + + + + + + )} + {children} diff --git a/fronts-client/src/components/feed/FeedItem.tsx b/fronts-client/src/components/feed/FeedItem.tsx index 9e179b98f86..3781a32854b 100644 --- a/fronts-client/src/components/feed/FeedItem.tsx +++ b/fronts-client/src/components/feed/FeedItem.tsx @@ -196,19 +196,27 @@ export class FeedItem extends React.Component { + > + {(props) => ( + <> + + + + + )} + ); diff --git a/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx b/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx index 6ede456615a..600dc257c70 100644 --- a/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx +++ b/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { styled } from 'constants/theme'; import ToolTip from './HoverActionToolTip'; import { CardSizes } from 'types/Collection'; @@ -33,84 +33,50 @@ const ToolTipWrapper = styled.div<{ : null}; `; -interface HoverButtonInterface { - text: string; - component: React.ComponentType; -} -export interface ButtonPropsFromWrapper { - showToolTip: () => void; +export interface ButtonProps { + showToolTip: (text: string) => void; hideToolTip: () => void; - isSnapLink?: boolean; + size?: CardSizes; } -interface WrapperProps { - buttons: HoverButtonInterface[]; - buttonProps: ButtonProps; + +interface WrapperProps { size?: CardSizes; // Article Component size toolTipPosition: 'top' | 'left' | 'bottom' | 'right'; toolTipAlign: 'left' | 'center' | 'right'; + children: (renderProps: ButtonProps) => JSX.Element; } -interface WrapperState { - isToolTipVisible: boolean; - toolTipText: string; -} - -class HoverActionsButtonWrapper extends React.Component< - WrapperProps, - WrapperState -> { - constructor(props: WrapperProps) { - super(props); - this.state = { - isToolTipVisible: false, - toolTipText: '', - }; - } +export const HoverActionsButtonWrapper = ({ + toolTipPosition, + toolTipAlign, + size, + children, +}: WrapperProps) => { + const [toolTipText, setToolTipText] = useState(undefined); - public render() { - const { buttons, buttonProps, toolTipPosition, toolTipAlign } = this.props; - const { isToolTipVisible, toolTipText } = this.state; - - return ( - - {isToolTipVisible ? ( - - - - ) : null} - {buttons.map((ButtonObj) => ( - { - this.showToolTip(ButtonObj.text); - }} - hideToolTip={() => { - this.hideToolTip(); - }} - /> - ))} - - ); - } - - private showToolTip = (text: string) => - this.setState({ - isToolTipVisible: true, - toolTipText: text, - }); + const showToolTip = (text: string) => { + setToolTipText(text); + }; - private hideToolTip = () => { - this.setState({ - isToolTipVisible: false, - }); + const hideToolTip = () => { + setToolTipText(undefined); }; -} -export { HoverActionsButtonWrapper, HoverButtonInterface }; + return ( + + {toolTipText !== undefined ? ( + + + + ) : null} + {children({ + showToolTip, + hideToolTip, + size: size, + })} + + ); +}; diff --git a/fronts-client/src/components/inputs/HoverActionButtons.tsx b/fronts-client/src/components/inputs/HoverActionButtons.tsx index 38885618cfc..f734329388b 100644 --- a/fronts-client/src/components/inputs/HoverActionButtons.tsx +++ b/fronts-client/src/components/inputs/HoverActionButtons.tsx @@ -2,7 +2,7 @@ import React from 'react'; import ButtonCircular from './ButtonCircular'; import Link from '../Link'; import { getPaths } from '../../util/paths'; -import { ButtonPropsFromWrapper } from './HoverActionButtonWrapper'; +import { ButtonProps } from './HoverActionButtonWrapper'; import { AddToClipboardHoverIcon, OphanHoverIcon, @@ -32,24 +32,20 @@ ActionButton.defaultProps = { danger: false, }; -interface ButtonPropsFromArticle { - isLive?: boolean; - urlPath?: string; - onDelete?: () => void; - onAddToClipboard?: () => void; -} - -type ButtonProps = ButtonPropsFromArticle & ButtonPropsFromWrapper; +type ButtonPropsWithHoverText = ButtonProps & { + hoverText: string; +}; const HoverDeleteButton = ({ showToolTip, hideToolTip, onDelete, -}: ButtonProps) => ( + hoverText, +}: ButtonPropsWithHoverText & { onDelete: () => void }) => ( showToolTip(hoverText)} onMouseLeave={hideToolTip} onClick={(e: React.MouseEvent) => { e.stopPropagation(); @@ -64,10 +60,11 @@ const HoverAddToClipboardButton = ({ showToolTip, hideToolTip, onAddToClipboard, -}: ButtonProps) => ( + hoverText, +}: ButtonPropsWithHoverText & { onAddToClipboard: () => void }) => ( showToolTip(hoverText)} onMouseLeave={hideToolTip} onClick={(e: React.MouseEvent) => { e.stopPropagation(); @@ -84,7 +81,12 @@ const HoverViewButton = ({ showToolTip, hideToolTip, isSnapLink = false, -}: ButtonProps) => ( + hoverText, +}: ButtonPropsWithHoverText & { + isLive?: boolean; + urlPath?: string; + isSnapLink?: boolean; +}) => ( { e.stopPropagation(); @@ -99,7 +101,7 @@ const HoverViewButton = ({ > showToolTip(hoverText)} onMouseLeave={hideToolTip} > @@ -113,7 +115,12 @@ const HoverOphanButton = ({ showToolTip, hideToolTip, isSnapLink = false, -}: ButtonProps) => + hoverText, +}: ButtonPropsWithHoverText & { + isLive?: boolean; + urlPath?: string; + isSnapLink?: boolean; +}) => isLive ? ( { @@ -128,7 +135,7 @@ const HoverOphanButton = ({ > showToolTip(hoverText)} onMouseLeave={hideToolTip} > diff --git a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx index d954e60e186..3a720d0aa67 100644 --- a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx +++ b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx @@ -14,29 +14,27 @@ import { } from '../HoverActionButtons'; import { ThemeProvider } from 'styled-components'; import { theme } from '../../../constants/theme'; +import { noop } from 'lodash'; afterEach(cleanup); -// Mocks // -const onDelete = () => {}; -const Buttons = [ - { text: 'View', component: HoverViewButton }, - { text: 'Ophan', component: HoverOphanButton }, - { text: 'Delete', component: HoverDeleteButton }, -]; - const HoverWrapper = ( - + + {(props) => ( + <> + + + + + )} + ); @@ -56,15 +54,28 @@ describe('Hover Action Button Wrapper', () => { const { container } = render( + > + {(props) => ( + <> + + + + + + )} + ); From e4a0e427ee6e503d94a52db658d0f797997e4ed0 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 13:51:53 +0100 Subject: [PATCH 02/10] Factor pathing logic out of buttons so we can reuse them in other cards --- .../components/card/article/ArticleBody.tsx | 38 ++++++----- .../components/card/snapLink/SnapLinkCard.tsx | 13 ++-- .../src/components/feed/FeedItem.tsx | 15 +++-- .../components/inputs/HoverActionButtons.tsx | 63 +++++++------------ .../inputs/__tests__/HoverActions.spec.tsx | 17 ++--- fronts-client/src/util/paths.ts | 7 ++- 6 files changed, 69 insertions(+), 84 deletions(-) diff --git a/fronts-client/src/components/card/article/ArticleBody.tsx b/fronts-client/src/components/card/article/ArticleBody.tsx index a53213286dd..deff58f87c4 100644 --- a/fronts-client/src/components/card/article/ArticleBody.tsx +++ b/fronts-client/src/components/card/article/ArticleBody.tsx @@ -33,6 +33,7 @@ import { ImageMetadataContainer } from 'components/image/ImageMetaDataContainer' import EditModeVisibility from 'components/util/EditModeVisibility'; import PageViewDataWrapper from '../../PageViewDataWrapper'; import ImageAndGraphWrapper from 'components/image/ImageAndGraphWrapper'; +import { getPaths } from 'util/paths'; const ThumbnailPlaceholder = styled(BasePlaceholder)` flex-shrink: 0; @@ -106,7 +107,7 @@ interface ArticleBodyProps { sectionName?: string; displayPlaceholders?: boolean; uuid: string; - onDelete: () => void; + onDelete?: () => void; onAddToClipboard?: () => void; isUneditable?: boolean; byline?: string; @@ -178,6 +179,7 @@ const articleBodyDefault = React.memo( }: ArticleBodyProps) => { const displayByline = size === 'default' && showByline && byline; const now = Date.now(); + const paths = urlPath ? getPaths(urlPath) : undefined; return ( <> @@ -327,14 +329,20 @@ const articleBodyDefault = React.memo( > {(props) => ( <> - - + {urlPath && ( + + )} + {isLive && ( + + )} {onAddToClipboard && ( )} - + {onDelete && ( + + )} )} diff --git a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx index 7b047d68578..347abd117d9 100644 --- a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx +++ b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx @@ -37,6 +37,7 @@ import { selectFeatureValue } from 'selectors/featureSwitchesSelectors'; import ImageAndGraphWrapper from 'components/image/ImageAndGraphWrapper'; import { ThumbnailCutout } from 'components/image/Thumbnail'; import PageViewDataWrapper from 'components/PageViewDataWrapper'; +import { getPathsForSnap } from 'util/paths'; const SnapLinkBodyContainer = styled(CardBody)` justify-content: space-between; @@ -198,14 +199,14 @@ const SnapLinkCard = ({ > {(props) => ( <> - + )} + - { handleDragStart, } = this.props; + const { preview, live } = getPaths(id); + const href = isLive ? live : preview; + return ( { > {(props) => ( <> - + - ( { e.stopPropagation(); }} - href={ - isSnapLink - ? urlPath - : isLive - ? getPaths(urlPath).live - : getPaths(urlPath).preview - } + href={href} > - isLive ? ( - { - e.stopPropagation(); - }} - href={ - isSnapLink - ? urlPath && getPaths(urlPath).ophan - : getPaths(`https://www.theguardian.com/${urlPath}`).ophan - } - data-testid={'ophan-hover-button'} + href?: string; +}) => ( + { + e.stopPropagation(); + }} + href={href} + data-testid={'ophan-hover-button'} + > + showToolTip(hoverText)} + onMouseLeave={hideToolTip} > - showToolTip(hoverText)} - onMouseLeave={hideToolTip} - > - - - - ) : null; - + + + +); export { HoverDeleteButton, HoverViewButton, diff --git a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx index 3a720d0aa67..cf9af472422 100644 --- a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx +++ b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx @@ -23,14 +23,8 @@ const HoverWrapper = ( {(props) => ( <> - - + + )} @@ -61,13 +55,10 @@ describe('Hover Action Button Wrapper', () => { <> - - + `https://www.theguardian.com/${path}`; const previewURIFromPath = (path: string) => `https://preview.gutools.co.uk/${path}`; -const getPaths = (uri: string) => { +export const getPathsForSnap = (path: string) => + getPaths(`https://www.theguardian.com/${path}`); + +export const getPaths = (uri: string) => { const path = /https:\/\/www\.theguardian.com(.+)/.test(uri) ? getPathFromUri(uri) : uri; @@ -28,5 +31,3 @@ const getPaths = (uri: string) => { preview: undefined, }; }; - -export { getPaths }; From db60a767744026f3b2b3a13ed0a1d059b6def323 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 13:52:30 +0100 Subject: [PATCH 03/10] Remove test for presence of Ophan button As we're now using that logic within the cards themselves --- .../inputs/__tests__/HoverActions.spec.tsx | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx index cf9af472422..46095cdbace 100644 --- a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx +++ b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx @@ -43,41 +43,6 @@ describe('Hover Action Button Wrapper', () => { expect(getByTitle('ophan')).toBeTruthy(); expect(getByTitle('delete')).toBeTruthy(); }); - - it('should render Wrapper without Ophan Button when Draft', () => { - const { container } = render( - - - {(props) => ( - <> - - - - - )} - - - ); - - const wrapper = container.firstChild as HTMLElement; - expect(wrapper.childNodes.length).toEqual(2); - // TODO explicitly check ophanButton is NOT rendered using queryByAltText - solve TS error in testing library - const ophanButton = wrapper.querySelector( - '[data-testid="ophan-hover-button"]' - ); - expect(ophanButton).toBeFalsy(); - }); }); describe('Hover Action Button ToolTip', () => { From 96e9db9569f0173c4bf14a4ae26c2a1d917e50de Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 14:40:08 +0100 Subject: [PATCH 04/10] Correct Ophan link --- .../src/components/card/article/ArticleBody.tsx | 2 +- fronts-client/src/components/feed/FeedItem.tsx | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/fronts-client/src/components/card/article/ArticleBody.tsx b/fronts-client/src/components/card/article/ArticleBody.tsx index deff58f87c4..e2eb2836d1f 100644 --- a/fronts-client/src/components/card/article/ArticleBody.tsx +++ b/fronts-client/src/components/card/article/ArticleBody.tsx @@ -339,7 +339,7 @@ const articleBodyDefault = React.memo( {isLive && ( )} diff --git a/fronts-client/src/components/feed/FeedItem.tsx b/fronts-client/src/components/feed/FeedItem.tsx index 3a7ac92bd36..7c27b953ffd 100644 --- a/fronts-client/src/components/feed/FeedItem.tsx +++ b/fronts-client/src/components/feed/FeedItem.tsx @@ -137,7 +137,7 @@ export class FeedItem extends React.Component { handleDragStart, } = this.props; - const { preview, live } = getPaths(id); + const { preview, live, ophan } = getPaths(id); const href = isLive ? live : preview; return ( @@ -206,12 +206,7 @@ export class FeedItem extends React.Component { {(props) => ( <> - + Date: Tue, 7 May 2024 14:46:34 +0100 Subject: [PATCH 05/10] Add leading slash to Ophan Previously added by adding the guardian URL to the path and passing the URL through 'getPaths', which is unnecessary --- fronts-client/src/components/feed/FeedItem.tsx | 4 +++- fronts-client/src/util/__tests__/paths.spec.ts | 3 +-- fronts-client/src/util/paths.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fronts-client/src/components/feed/FeedItem.tsx b/fronts-client/src/components/feed/FeedItem.tsx index 7c27b953ffd..19999d915ed 100644 --- a/fronts-client/src/components/feed/FeedItem.tsx +++ b/fronts-client/src/components/feed/FeedItem.tsx @@ -206,7 +206,9 @@ export class FeedItem extends React.Component { {(props) => ( <> - + {isLive && ( + + )} { it('creates correct ophan URI from URL', () => { - expect(getPaths(testURL).ophan).toEqual( + expect(getPaths(testURLPath).ophan).toEqual( 'https://dashboard.ophan.co.uk/info?path=/society/2018/oct/16/labour-seeks-to-force-publication-of-universal-credit-impact-analysis' ); }); diff --git a/fronts-client/src/util/paths.ts b/fronts-client/src/util/paths.ts index 6249ffdac1b..db646a88184 100644 --- a/fronts-client/src/util/paths.ts +++ b/fronts-client/src/util/paths.ts @@ -4,7 +4,7 @@ const getPathFromUri = (uri: string): string | void => { }; const ophanURIFromPath = (path: string) => - `https://dashboard.ophan.co.uk/info?path=${path}`; + `https://dashboard.ophan.co.uk/info?path=/${path}`; const liveURIFromPath = (path: string) => `https://www.theguardian.com/${path}`; From 6d9403f610fe6cf0756c4ecbd1357844134c9076 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 14:59:28 +0100 Subject: [PATCH 06/10] Add overlay buttons to Recipe container card --- .../src/components/card/recipe/RecipeCard.tsx | 41 ++++++++++++++++++- .../src/components/feed/ArticleFeedItem.tsx | 2 + .../src/components/feed/FeedItem.tsx | 6 ++- .../src/components/feed/RecipeFeedItem.tsx | 2 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/fronts-client/src/components/card/recipe/RecipeCard.tsx b/fronts-client/src/components/card/recipe/RecipeCard.tsx index 70bef5e7dbc..ad2001f0dd4 100644 --- a/fronts-client/src/components/card/recipe/RecipeCard.tsx +++ b/fronts-client/src/components/card/recipe/RecipeCard.tsx @@ -16,12 +16,20 @@ import { ThumbnailSmall } from 'components/image/Thumbnail'; import CardMetaContent from '../CardMetaContent'; import { upperFirst } from 'lodash'; import { useSelector } from 'react-redux'; +import { HoverActionsAreaOverlay } from 'components/CollectionHoverItems'; +import { HoverActionsButtonWrapper } from 'components/inputs/HoverActionButtonWrapper'; +import { + HoverAddToClipboardButton, + HoverDeleteButton, + HoverViewButton, +} from 'components/inputs/HoverActionButtons'; +import { getPaths } from 'util/paths'; interface Props { onDragStart?: (d: React.DragEvent) => void; onDrop?: (d: React.DragEvent) => void; - onDelete?: (uuid: string) => void; - onAddToClipboard?: (uuid: string) => void; + onDelete: () => void; + onAddToClipboard: () => void; onClick?: () => void; id: string; collectionId?: string; @@ -53,6 +61,9 @@ export const RecipeCard = ({ const recipe = useSelector((state) => recipeSelectors.selectById(state, card.id) ); + const paths = recipe?.canonicalArticle + ? getPaths(recipe.canonicalArticle) + : undefined; return ( @@ -82,6 +93,32 @@ export const RecipeCard = ({ + + + {(props) => ( + <> + + + + + )} + + ); diff --git a/fronts-client/src/components/feed/ArticleFeedItem.tsx b/fronts-client/src/components/feed/ArticleFeedItem.tsx index 63dc1f54aed..8a868792342 100644 --- a/fronts-client/src/components/feed/ArticleFeedItem.tsx +++ b/fronts-client/src/components/feed/ArticleFeedItem.tsx @@ -20,6 +20,7 @@ import { insertCardWithCreate } from '../../actions/Cards'; import { connect } from 'react-redux'; import { FeedItem } from './FeedItem'; import { ContentInfo } from './ContentInfo'; +import { CardTypesMap } from 'constants/cardTypes'; const Tone = styled.span` font-weight: normal; @@ -56,6 +57,7 @@ const ArticleFeedItemComponent = ({ return ( { public render() { const { id, + type, title, liveUrl, isLive, @@ -139,6 +142,7 @@ export class FeedItem extends React.Component { const { preview, live, ophan } = getPaths(id); const href = isLive ? live : preview; + const displayOphanLink = type === CardTypesMap.ARTICLE && isLive; return ( { {(props) => ( <> - {isLive && ( + {displayOphanLink && ( )} Date: Tue, 7 May 2024 17:06:03 +0100 Subject: [PATCH 07/10] Add clipboard callback to feed items --- .../src/components/feed/RecipeFeedItem.tsx | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/fronts-client/src/components/feed/RecipeFeedItem.tsx b/fronts-client/src/components/feed/RecipeFeedItem.tsx index 7d98255d9d0..79c6e6511aa 100644 --- a/fronts-client/src/components/feed/RecipeFeedItem.tsx +++ b/fronts-client/src/components/feed/RecipeFeedItem.tsx @@ -1,26 +1,39 @@ import { Recipe } from '../../types/Recipe'; import { FeedItem } from './FeedItem'; -import React from 'react'; +import React, { useCallback } from 'react'; import { State } from '../../types/State'; import { dragOffsetX, dragOffsetY, } from '../FrontsEdit/CollectionComponents/ArticleDrag'; -import noop from 'lodash/noop'; import { selectFeatureValue } from '../../selectors/featureSwitchesSelectors'; -import { connect } from 'react-redux'; import { ContentInfo } from './ContentInfo'; import { CardTypesMap } from 'constants/cardTypes'; +import { useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; +import { insertCardWithCreate } from 'actions/Cards'; interface ComponentProps { recipe: Recipe; - shouldObscureFeed: boolean; } -export const RecipeFeedItemComponent = ({ - recipe, - shouldObscureFeed, -}: ComponentProps) => { +export const RecipeFeedItem = ({ recipe }: ComponentProps) => { + const shouldObscureFeed = useSelector((state) => + selectFeatureValue(state, 'obscure-feed') + ); + + const dispatch = useDispatch(); + + const onAddToClipboard = useCallback(() => { + dispatch( + insertCardWithCreate( + { type: 'clipboard', id: 'clipboard', index: 0 }, + { type: 'RECIPE', data: recipe }, + 'clipboard' + ) + ); + }, [recipe]); + const handleDragStart = ( event: React.DragEvent, dragNode: HTMLDivElement @@ -41,15 +54,9 @@ export const RecipeFeedItemComponent = ({ hasVideo={false} isLive={true} // We do not yet serve preview recipes handleDragStart={handleDragStart} - onAddToClipboard={noop} + onAddToClipboard={onAddToClipboard} shouldObscureFeed={shouldObscureFeed} metaContent={Recipe} /> ); }; - -const mapStateToProps = (state: State) => ({ - shouldObscureFeed: selectFeatureValue(state, 'obscure-feed'), -}); - -export const RecipeFeedItem = connect(mapStateToProps)(RecipeFeedItemComponent); From 20a804b11b0fa21a9aff2f04d49f28e2be391439 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 7 May 2024 17:16:22 +0100 Subject: [PATCH 08/10] Move to specific render prop --- .../src/components/card/article/ArticleBody.tsx | 5 ++--- fronts-client/src/components/card/recipe/RecipeCard.tsx | 5 ++--- .../src/components/card/snapLink/SnapLinkCard.tsx | 5 ++--- fronts-client/src/components/feed/FeedItem.tsx | 5 ++--- .../src/components/inputs/HoverActionButtonWrapper.tsx | 6 +++--- .../components/inputs/__tests__/HoverActions.spec.tsx | 9 +++++---- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/fronts-client/src/components/card/article/ArticleBody.tsx b/fronts-client/src/components/card/article/ArticleBody.tsx index e2eb2836d1f..666b4191c85 100644 --- a/fronts-client/src/components/card/article/ArticleBody.tsx +++ b/fronts-client/src/components/card/article/ArticleBody.tsx @@ -326,8 +326,7 @@ const articleBodyDefault = React.memo( size={size} toolTipPosition={'top'} toolTipAlign={'right'} - > - {(props) => ( + renderButtons={(props) => ( <> {urlPath && ( )} - + /> ); diff --git a/fronts-client/src/components/card/recipe/RecipeCard.tsx b/fronts-client/src/components/card/recipe/RecipeCard.tsx index ad2001f0dd4..fb2c4dc00db 100644 --- a/fronts-client/src/components/card/recipe/RecipeCard.tsx +++ b/fronts-client/src/components/card/recipe/RecipeCard.tsx @@ -97,8 +97,7 @@ export const RecipeCard = ({ - {(props) => ( + renderButtons={(props) => ( <> )} - + /> diff --git a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx index 347abd117d9..d442b4524f9 100644 --- a/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx +++ b/fronts-client/src/components/card/snapLink/SnapLinkCard.tsx @@ -196,8 +196,7 @@ const SnapLinkCard = ({ size={size} toolTipPosition={'top'} toolTipAlign={'right'} - > - {(props) => ( + renderButtons={(props) => ( <> {urlPath && ( @@ -219,7 +218,7 @@ const SnapLinkCard = ({ /> )} - + /> {children} diff --git a/fronts-client/src/components/feed/FeedItem.tsx b/fronts-client/src/components/feed/FeedItem.tsx index 71f0f3f44f5..fb692377d65 100644 --- a/fronts-client/src/components/feed/FeedItem.tsx +++ b/fronts-client/src/components/feed/FeedItem.tsx @@ -206,8 +206,7 @@ export class FeedItem extends React.Component { - {(props) => ( + renderButtons={(props) => ( <> {displayOphanLink && ( @@ -220,7 +219,7 @@ export class FeedItem extends React.Component { /> )} - + /> ); diff --git a/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx b/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx index 600dc257c70..d4f8c043336 100644 --- a/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx +++ b/fronts-client/src/components/inputs/HoverActionButtonWrapper.tsx @@ -43,14 +43,14 @@ interface WrapperProps { size?: CardSizes; // Article Component size toolTipPosition: 'top' | 'left' | 'bottom' | 'right'; toolTipAlign: 'left' | 'center' | 'right'; - children: (renderProps: ButtonProps) => JSX.Element; + renderButtons: (renderProps: ButtonProps) => JSX.Element; } export const HoverActionsButtonWrapper = ({ toolTipPosition, toolTipAlign, size, - children, + renderButtons, }: WrapperProps) => { const [toolTipText, setToolTipText] = useState(undefined); @@ -72,7 +72,7 @@ export const HoverActionsButtonWrapper = ({ ) : null} - {children({ + {renderButtons({ showToolTip, hideToolTip, size: size, diff --git a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx index 46095cdbace..f7fa76330bf 100644 --- a/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx +++ b/fronts-client/src/components/inputs/__tests__/HoverActions.spec.tsx @@ -20,19 +20,20 @@ afterEach(cleanup); const HoverWrapper = ( - - {(props) => ( + ( <> )} - + /> ); -// Tests // describe('Hover Action Button Wrapper', () => { it('should render Wrapper with Buttons', () => { const { container, getByTitle } = render(HoverWrapper); From 9e87c1a951d897596c5c11648c47442508c40c0e Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 9 May 2024 17:17:42 +0100 Subject: [PATCH 09/10] =?UTF-8?q?ID=20of=20feed=20item=20is=20actually=20h?= =?UTF-8?q?ref=20=E2=80=93=20correct=20in=20follow=20up=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fronts-client/src/components/feed/RecipeFeedItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fronts-client/src/components/feed/RecipeFeedItem.tsx b/fronts-client/src/components/feed/RecipeFeedItem.tsx index 79c6e6511aa..b3e3505947a 100644 --- a/fronts-client/src/components/feed/RecipeFeedItem.tsx +++ b/fronts-client/src/components/feed/RecipeFeedItem.tsx @@ -47,7 +47,7 @@ export const RecipeFeedItem = ({ recipe }: ComponentProps) => { return ( Date: Thu, 9 May 2024 17:57:34 +0100 Subject: [PATCH 10/10] Add type for ChefFeedItem --- fronts-client/src/components/feed/ChefFeedItem.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fronts-client/src/components/feed/ChefFeedItem.tsx b/fronts-client/src/components/feed/ChefFeedItem.tsx index 21f8de34401..2709cec826b 100644 --- a/fronts-client/src/components/feed/ChefFeedItem.tsx +++ b/fronts-client/src/components/feed/ChefFeedItem.tsx @@ -10,6 +10,7 @@ import { selectFeatureValue } from '../../selectors/featureSwitchesSelectors'; import { State } from '../../types/State'; import { connect } from 'react-redux'; import noop from 'lodash/noop'; +import { CardTypesMap } from 'constants/cardTypes'; interface ComponentProps { chef: Chef; @@ -33,6 +34,7 @@ export const ChefFeedItemComponent = ({ return (