Skip to content

Commit

Permalink
Remove length limits for all interactive messages
Browse files Browse the repository at this point in the history
  • Loading branch information
haomingli2020 committed Mar 21, 2024
1 parent d89b532 commit fc4865e
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 154 deletions.
63 changes: 63 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion local-testing/amazon-connect-chat-interface.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PT from "prop-types";
import { RichMessageRenderer } from "../../../RichMessageComponents";
import { InteractiveMessage, MessageBody } from "../InteractiveMessage";
import { Button } from "connect-core";
import { truncateStrFromCharLimit, truncateElementFromLimit } from "../../../../../utils/helper";
import { truncateStrFromCharLimit } from "../../../../../utils/helper";
import isJSON from "is-json";
import { InteractiveMessageType } from "../../../datamodel/Model";

Expand Down Expand Up @@ -142,7 +142,6 @@ export default function Carousel({ content, addMessage }) {

// Frontend field validations
const title = truncateStrFromCharLimit(inputTitle, InteractiveMessageType.CAROUSEL, "titleCharLimit");
const elements = truncateElementFromLimit(inputElems, InteractiveMessageType.CAROUSEL, "elementsRenderedMax");

return (
<>
Expand All @@ -160,7 +159,7 @@ export default function Carousel({ content, addMessage }) {
</ScrollButton>

<ResponsesSection ref={scrollerRef} data-testid='interactive-carousel-response-section'>
<NestedInteractiveMessages elements={elements} addMessage={addMessage} />
<NestedInteractiveMessages elements={inputElems} addMessage={addMessage} />
</ResponsesSection>

<ScrollButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,22 +177,6 @@ describe("<Carousel />", () => {
});
});

it("Should only render up to 5 nested pickers", () => {
const carouselOverFiveLimit = {
...mockCarouselContent,
elements: [
...mockCarouselContent.elements,
mockNestedPanelPickerFlights,
mockNestedPanelPickerHotels,
mockNestedListPickerDining,
mockNestedPanelPickerFlights,
],
};
renderElement({ ...mockProps, content: carouselOverFiveLimit });

expect(screen.getAllByText("Select an option:")).toHaveLength(5);
});

it("Should render reply option buttons and be accessible", () => {
renderElement(mockProps);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
PickerOptionTitle,
PickerElementLinkOption
} from "../InteractiveMessage";
import { createInteractiveMessagePayload, truncateElementFromLimit, truncateStrFromCharLimit } from "../../../../../utils/helper";
import { createInteractiveMessagePayload, truncateStrFromCharLimit } from "../../../../../utils/helper";
import { InteractiveMessageSelectionType, InteractiveMessageType } from "../../../datamodel/Model";
import { RichMessageRenderer } from "../../../RichMessageComponents";

Expand Down Expand Up @@ -147,7 +147,6 @@ export default function ListPicker({
// Frontend field validations
const title = truncateStrFromCharLimit(inputTitle, InteractiveMessageType.LIST_PICKER, "titleCharLimit");
const subtitle = truncateStrFromCharLimit(inputSubtitle, InteractiveMessageType.LIST_PICKER, "subtitleCharLimit");
const elements = truncateElementFromLimit(inputElements, InteractiveMessageType.LIST_PICKER, "elementsRenderedMax");

const [imageLoaded, setImageLoaded] = useState(false);
const [elementImagesLoadedCount, setElementImagesLoadedCount] = useState(0);
Expand All @@ -161,7 +160,7 @@ export default function ListPicker({
}

function onItemClick(index) {
const selectedElement = elements[index];
const selectedElement = inputElements[index];
const payload = createInteractiveMessagePayload(
selectedElement,
preIndex,
Expand All @@ -177,10 +176,10 @@ export default function ListPicker({
}

const showElementImages = () => {
const actionBtnCount = elements.filter((ele) => {
const actionBtnCount = inputElements.filter((ele) => {
return ele.actionDetail;
}).length;
return elementImagesLoadedCount === elements.length - actionBtnCount;
return elementImagesLoadedCount === inputElements.length - actionBtnCount;
};

return (
Expand All @@ -197,7 +196,7 @@ export default function ListPicker({
<HeaderText title={title} subtitle={subtitle} />
<ResponsesSection isCarouselElem={isCarouselElem}>
<div>
{elements.map((listPickerElement, index) => (
{inputElements.map((listPickerElement, index) => (
<ListPickerElement
key={"element-" + index}
element={listPickerElement}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,6 @@ describe("<ListPicker />", () => {
createMsgPayloadSpy.mockRestore();
});

it("Should only render max number of elements", () => {
const { elementsRenderedMax } = LIST_PICKER_CONSTRAINTS;

const listPickerOverElementLimit = {
...mockListPickerContent,
elements: Array.apply(null, Array(elementsRenderedMax + 3)).map((e, index) => ({ title: `ListPickerElement${index}` })),
};
renderElement({ ...mockProps, content: listPickerOverElementLimit });

const elementOptions = screen.getAllByRole("button");
expect(elementOptions).toHaveLength(elementsRenderedMax);
expect(() => screen.getByText(`ListPickerElement${elementsRenderedMax}`)).toThrow(
"Unable to find an element"
);
expect(() => screen.getByText(`ListPickerElement${elementsRenderedMax - 1}`)).not.toThrow();
});

it.each([
["title", LIST_PICKER_CONSTRAINTS.titleCharLimit],
["subtitle", LIST_PICKER_CONSTRAINTS.subtitleCharLimit]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import styled from "styled-components";
import PT from "prop-types";
import { InteractiveMessageSelectionType, InteractiveMessageType } from "../../../datamodel/Model";
import { createInteractiveMessagePayload, truncateElementFromLimit, truncateStrFromCharLimit } from "../../../../../utils/helper";
import { createInteractiveMessagePayload, truncateStrFromCharLimit } from "../../../../../utils/helper";

//#region Styled Components
const ImageContainer = styled.div`
Expand Down Expand Up @@ -96,7 +96,6 @@ export default function Panel({
// Frontend field validations
const title = truncateStrFromCharLimit(inputTitle, InteractiveMessageType.PANEL, "titleCharLimit");
const subtitle = truncateStrFromCharLimit(inputSubtitle, InteractiveMessageType.PANEL, "subtitleCharLimit");
const elements = truncateElementFromLimit(inputElements, InteractiveMessageType.PANEL, "elementsRenderedMax");

const [imageLoaded, setImageLoaded] = useState(false);

Expand All @@ -105,7 +104,7 @@ export default function Panel({
}

function onItemClick(index) {
const selectedElement = elements[index];
const selectedElement = inputElements[index];
const payload = createInteractiveMessagePayload(
selectedElement,
preIndex,
Expand Down Expand Up @@ -134,7 +133,7 @@ export default function Panel({
<HeaderText title={title} subtitle={subtitle} />
<ResponsesSection isCarouselElem={isCarouselElem}>
<div>
{elements.map((element, index) => (
{inputElements.map((element, index) => (
<PanelPickerElement
key={"element-" + index}
handleButtonClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,6 @@ describe("<Panel />", () => {
createMsgPayloadSpy.mockRestore();
});

it("Should only render max number of elements", () => {
const { elementsRenderedMax } = PANEL_CONSTRAINTS;

const panelOverElementLimit = {
...mockPanelContent,
elements: Array.apply(null, Array(elementsRenderedMax + 3)).map((e, index) => ({ title: `PanelElement${index}` })),
};
renderElement({ ...mockProps, content: panelOverElementLimit });

const elementOptions = screen.getAllByRole("button");
expect(elementOptions).toHaveLength(elementsRenderedMax);
expect(() => screen.getByText(`PanelElement${elementsRenderedMax}`)).toThrow(
"Unable to find an element"
);
expect(() => screen.getByText(`PanelElement${elementsRenderedMax - 1}`)).not.toThrow();
});

it.each([
["title", PANEL_CONSTRAINTS.titleCharLimit],
["subtitle", PANEL_CONSTRAINTS.subtitleCharLimit]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default function QuickReply({ content, addMessage }) {
<RichMessageRenderer content={title} />
</MessageBody>
<ResponsesSection data-testid="interactive-quickreply-response-section">
{elements.slice(0, 5).map((element, index) => (
{elements.map((element, index) => (
<ReplyElement
element={element}
handleSelection={addMessage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,25 +97,6 @@ describe("<QuickReply />", () => {
});
});

it("Should only render up to 5 elements", () => {
const { elementsRenderedMax } = QUICK_REPLY_CONSTRAINTS;

const quickReplyOverFiveLimit = {
...mockQuickReplyContent,
elements: [
...mockQuickReplyContent.elements,
{ title: "Ignored Option #6!" },
],
};
renderElement({ ...mockProps, content: quickReplyOverFiveLimit });

const quickReplyOptions = screen.getAllByRole("button");
expect(quickReplyOptions).toHaveLength(elementsRenderedMax);
expect(() => screen.getByText("Ignored Option #6!")).toThrow(
"Unable to find an element"
);
});

it("Should truncate a title over the character limit", () => {
const { titleCharLimit } = QUICK_REPLY_CONSTRAINTS;

Expand Down
24 changes: 0 additions & 24 deletions src/utils/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,11 @@ export const INTERACTIVE_MESSAGE_CONSTRAINTS = {
[InteractiveMessageType.PANEL]: {
titleCharLimit: 400,
subtitleCharLimit: 400,
elementsRenderedMax: 10,
elementTitleCharLimit: 400
},
[InteractiveMessageType.LIST_PICKER]: {
titleCharLimit: 400,
subtitleCharLimit: 400,
elementsRenderedMax: 6,
elementTitleCharLimit: 400,
elementSubtitleCharLimit: 400,
},
Expand All @@ -92,11 +90,9 @@ export const INTERACTIVE_MESSAGE_CONSTRAINTS = {
},
[InteractiveMessageType.CAROUSEL]: {
titleCharLimit: 400,
elementsRenderedMax: 5,
},
[InteractiveMessageType.QUICK_REPLY]: {
titleCharLimit: 400,
elementsRenderedMax: 5,
replyOptionCharLimit: 200,
}
}
Expand Down Expand Up @@ -132,23 +128,3 @@ export const truncateStrFromCharLimit = (str, InteractiveMessageType, fieldLimit
return sanitizedStr.substring(0, MAX_LENGTH) + "...";
}
}

/**
* Truncates an array of elements based on the specified minimum and maximum limits.
*
* @param {Array} elements - The array of elements to truncate.
* @param {string} InteractiveMessageType - interactive message templateType.
* @param {string} elementsRenderedMaxKey - key to retrieve max constraint from INTERACTIVE_MESSAGE_CONSTRAINTS.
* @returns {Array} The truncated array of elements.
*/
export const truncateElementFromLimit = (elements, InteractiveMessageType, elementsRenderedMaxKey) => {
const templateContraints = INTERACTIVE_MESSAGE_CONSTRAINTS[InteractiveMessageType] || {};
const MAX_LIMIT = templateContraints[elementsRenderedMaxKey] || elements.length ;

if (elements.length > MAX_LIMIT) {
console.warn(`[${InteractiveMessageType} template] ${elementsRenderedMaxKey} of ${MAX_LIMIT} was exceeded`)
return elements.slice(0, MAX_LIMIT);
}

return elements;
}
Loading

0 comments on commit fc4865e

Please sign in to comment.