Skip to content

Commit

Permalink
fronts integration PLUS 'suggest alternate crops' buttons (for compos…
Browse files Browse the repository at this point in the history
…er trail image, see guardian/flexible-content#4984)
  • Loading branch information
twrichards committed Oct 11, 2024
1 parent 9a2870b commit 1cd536b
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 55 deletions.
7 changes: 7 additions & 0 deletions bootstrapping-lambda/local/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ <h3>Override unread notifications bubble</h3>
<button id="btn-unset-unread-notifications-bubble">Unset</button>
</div>

<h3>Fronts Integration</h3>
<pinboard-article-button
data-url-path="football/2024/oct/08/tottenham-ryan-mason-anderlecht-manager-job"
></pinboard-article-button>
<pinboard-suggest-alternate-crops
data-media-id="d6518ba44eb272830b779e4ed6356482007d4536"
></pinboard-suggest-alternate-crops>
<h3><code>Add to 📌</code> button</h3>
<ul id="button_section">
<h4>present initially</h4>
Expand Down
45 changes: 8 additions & 37 deletions client/src/addToPinboardButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import ReactDOM from "react-dom";
import React, { ReactPortal, useContext } from "react";
import PinIcon from "../icons/pin-icon.svg";
import { css } from "@emotion/react";
import { pinboard, pinMetal } from "../colours";
import { buildPayloadAndType, PayloadAndType } from "./types/PayloadAndType";
import { space } from "@guardian/source-foundations";
import { agateSans } from "../fontNormaliser";
Expand All @@ -13,35 +11,10 @@ import {
IMAGINE_REQUEST_TYPES,
IMAGING_REQUEST_ITEM_TYPE,
} from "shared/octopusImaging";
import { ButtonInOtherTools } from "./buttonInOtherTools";

export const ASSET_HANDLE_HTML_TAG = "asset-handle";

const buttonCss = css`
display: flex;
align-items: center;
background-color: ${pinboard[500]};
${agateSans.xxsmall({ fontWeight: "bold" })};
border: none;
border-radius: 100px;
padding: 0 6px 0 10px;
line-height: 2;
cursor: pointer;
color: ${pinMetal};
`;

const pinIcon = (
<PinIcon
css={css`
height: 14px;
margin-left: 2px;
path {
stroke: ${pinMetal};
stroke-width: 1px;
}
`}
/>
);

interface AddToPinboardButtonProps {
dataAttributes: DOMStringMap;
setPayloadToBeSent: (payload: PayloadAndType | null) => void;
Expand Down Expand Up @@ -75,23 +48,23 @@ const AddToPinboardButton = (props: AddToPinboardButtonProps) => {
${agateSans.small()}
`}
>
<button
<ButtonInOtherTools
iconAtEnd
onClick={() => {
props.setPayloadToBeSent(payloadToBeSent);
props.expand();
sendTelemetryEvent?.(PINBOARD_TELEMETRY_TYPE.ADD_TO_PINBOARD_BUTTON, {
assetType: payloadToBeSent.type,
});
}}
css={buttonCss}
>
{payloadToBeSent.type === "grid-search"
? "Add this search to"
: "Add to"}
{pinIcon}
</button>
</ButtonInOtherTools>
{payloadToBeSent.type === "grid-original" && (
<button
<ButtonInOtherTools
iconAtEnd
onClick={() => {
props.setPayloadToBeSent({
type: IMAGING_REQUEST_ITEM_TYPE,
Expand All @@ -108,15 +81,13 @@ const AddToPinboardButton = (props: AddToPinboardButtonProps) => {
}
);
}}
css={css`
${buttonCss};
extraCss={css`
white-space: nowrap;
margin-top: ${space[1]}px;
`}
>
Imaging order
{pinIcon}
</button>
</ButtonInOtherTools>
)}
</root.div>
);
Expand Down
43 changes: 43 additions & 0 deletions client/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ import { getAgateFontFaceIfApplicable } from "../fontNormaliser";
import { Global } from "@emotion/react";
import { TourStateProvider } from "./tour/tourState";
import { demoMentionableUsers, demoUser } from "./tour/tourConstants";
import {
FRONTS_PINBOARD_ELEMENTS_QUERY_SELECTOR,
FrontsIntegration,
} from "./fronts/frontsIntegration";
import {
SUGGEST_ALTERNATE_CROP_QUERY_SELECTOR,
SuggestAlternateCrops,
} from "./fronts/suggestAlternateCrops";

const PRESELECT_PINBOARD_HTML_TAG = "pinboard-preselect";
const PRESET_UNREAD_NOTIFICATIONS_COUNT_HTML_TAG = "pinboard-bubble-preset";
Expand All @@ -67,6 +75,11 @@ export const PinBoardApp = ({
const [workflowPinboardElements, setWorkflowPinboardElements] = useState<
HTMLElement[]
>([]);
const [frontsPinboardElements, setFrontsPinboardElements] = useState<
HTMLElement[]
>([]);
const [alternateCropSuggestionElements, setAlternateCropSuggestionElements] =
useState<HTMLElement[]>([]);

const [maybeInlineSelectedPinboardId, _setMaybeInlineSelectedPinboardId] =
useState<string | null>(null);
Expand Down Expand Up @@ -95,6 +108,20 @@ export const PinBoardApp = ({
)
);

const refreshFrontsPinboardElements = () =>
setFrontsPinboardElements(
Array.from(
document.querySelectorAll(FRONTS_PINBOARD_ELEMENTS_QUERY_SELECTOR)
)
);

const refreshAlternateCropSuggestionElements = () =>
setAlternateCropSuggestionElements(
Array.from(
document.querySelectorAll(SUGGEST_ALTERNATE_CROP_QUERY_SELECTOR)
)
);

const refreshPreselectedPinboard = () => {
const preselectPinboardHTMLElement: HTMLElement | null =
document.querySelector(PRESELECT_PINBOARD_HTML_TAG);
Expand Down Expand Up @@ -129,6 +156,8 @@ export const PinBoardApp = ({
// Add nodes that already exist at time React app is instantiated
refreshAssetHandleNodes();
refreshWorkflowPinboardElements();
refreshFrontsPinboardElements();
refreshAlternateCropSuggestionElements();

refreshPreselectedPinboard();

Expand All @@ -138,6 +167,8 @@ export const PinBoardApp = ({
new MutationObserver(() => {
refreshAssetHandleNodes();
refreshWorkflowPinboardElements();
refreshFrontsPinboardElements();
refreshAlternateCropSuggestionElements();
refreshPreselectedPinboard();
refreshPresetUnreadNotifications();
}).observe(document.body, {
Expand Down Expand Up @@ -436,6 +467,18 @@ export const PinBoardApp = ({
)}
</TickContext.Provider>
</root.div>
{frontsPinboardElements.length > 0 && (
<FrontsIntegration
frontsPinboardElements={frontsPinboardElements}
/>
)}
{alternateCropSuggestionElements.length > 0 && (
<SuggestAlternateCrops
alternateCropSuggestionElements={
alternateCropSuggestionElements
}
/>
)}
{assetHandles.map((node, index) => (
<AddToPinboardButtonPortal
key={index}
Expand Down
47 changes: 47 additions & 0 deletions client/src/buttonInOtherTools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { PropsWithChildren } from "react";
import { css, SerializedStyles } from "@emotion/react";
import { pinboard, pinMetal } from "../colours";
import PinIcon from "../icons/pin-icon.svg";
import { agateSans } from "../fontNormaliser";

interface ButtonInOtherToolsProps {
iconAtEnd?: true;
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
extraCss?: SerializedStyles;
}
export const ButtonInOtherTools = ({
children,
iconAtEnd,
onClick,
extraCss,
}: PropsWithChildren<ButtonInOtherToolsProps>) => (
<button
onClick={onClick}
css={css`
display: flex;
align-items: center;
background-color: ${pinboard[500]};
${agateSans.xxsmall({ fontWeight: "bold" })};
border: none;
border-radius: 100px;
padding: 0 ${iconAtEnd ? 6 : 10}px 0 ${iconAtEnd ? 10 : 6}px;
line-height: 2;
cursor: pointer;
color: ${pinMetal};
${extraCss};
`}
>
{iconAtEnd && children}
<PinIcon
css={css`
height: 14px;
margin-${iconAtEnd ? "left" : "right"}: 2px;
path {
stroke: ${pinMetal};
stroke-width: 1px;
}
`}
/>
{!iconAtEnd && children}
</button>
);
Loading

0 comments on commit 1cd536b

Please sign in to comment.