From 9fb76667c4e15d8b15fcf4378abe667146e94011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Ravent=C3=B3s?= <36898236+Iru89@users.noreply.github.com> Date: Fri, 29 Nov 2024 16:53:27 +0100 Subject: [PATCH] Remove strings that refer components #BLT-1258 (#2943) ## Description @botonic/react Remove string that refer to @botonic/react components as Text, Button, MultichannelText etc @botonic/dx-bundler-rspack Remove comment Update README --- package-lock.json | 2 +- packages/botonic-dx-bundler-rspack/README.md | 32 +++++++- .../baseline/rspack.config.ts | 80 +++++++++---------- packages/botonic-react/package.json | 2 +- .../botonic-react/src/components/element.jsx | 15 +--- .../multichannel/multichannel-button.jsx | 2 +- .../multichannel/multichannel-carousel.jsx | 12 +-- .../multichannel/multichannel-text.jsx | 6 +- .../multichannel/multichannel-utils.js | 72 ++++++++++------- .../components/multichannel/multichannel.jsx | 19 +++-- .../multichannel/whatsapp/constants.ts | 10 +++ .../src/components/whatsapp-button-list.tsx | 2 +- .../components/whatsapp-cta-url-button.tsx | 2 +- packages/botonic-react/src/constants.js | 7 -- 14 files changed, 154 insertions(+), 109 deletions(-) create mode 100644 packages/botonic-react/src/components/multichannel/whatsapp/constants.ts diff --git a/package-lock.json b/package-lock.json index 35cfc4a15a..75bec7db73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26687,7 +26687,7 @@ }, "packages/botonic-react": { "name": "@botonic/react", - "version": "0.30.5", + "version": "0.30.6", "license": "MIT", "dependencies": { "@botonic/core": "^0.30.0", diff --git a/packages/botonic-dx-bundler-rspack/README.md b/packages/botonic-dx-bundler-rspack/README.md index 7f4198b501..a2a770b6ac 100644 --- a/packages/botonic-dx-bundler-rspack/README.md +++ b/packages/botonic-dx-bundler-rspack/README.md @@ -8,12 +8,32 @@ This package simplifies the configuration of a rspack bundler to build a Botonic - Webviews imported inside the webviews/index.ts must be classes or functions but cannot be arrow functions. +Do: + +```` +export function MyWebview(){ + ... + return +} +``` + +instead of: +```` + +export const MyWebview = () => { +... +return +} + +``` ## Setup - Install this package. ``` + npm install -D @botonic/dx-bundler-rspack + ``` - Copy `baseline/rspack.config.js` file to the root of your project. @@ -21,11 +41,15 @@ npm install -D @botonic/dx-bundler-rspack - Add this script to your package.json to build for production and start for development in local. ``` + ... "scipts": { - ... - "build_production": "ENVIRONMENT=production NODE_ENV=production rspack build --env target=all --mode=production", - "start": "ENVIRONMENT=local NODE_ENV=development rspack serve --env target=dev --mode=development", - ... +... +"build_production": "ENVIRONMENT=production NODE_ENV=production rspack build --env target=all --mode=production", +"start": "ENVIRONMENT=local NODE_ENV=development rspack serve --env target=dev --mode=development", +... } + +``` + ``` diff --git a/packages/botonic-dx-bundler-rspack/baseline/rspack.config.ts b/packages/botonic-dx-bundler-rspack/baseline/rspack.config.ts index 415fdce0b2..7684267715 100644 --- a/packages/botonic-dx-bundler-rspack/baseline/rspack.config.ts +++ b/packages/botonic-dx-bundler-rspack/baseline/rspack.config.ts @@ -70,54 +70,52 @@ const resolveConfig = { const isDev = String(process.env.ENVIRONMENT) === 'local' -const typescriptLoaderConfig = - // exclude: /node_modules[/\\](?!(@botonic\/(core|react))[/\\])/, - [ - { - test: /\.tsx?$/, - exclude: [/node_modules/], - use: { - loader: 'builtin:swc-loader', - options: { - jsc: { - parser: { - syntax: 'typescript', - tsx: true, - }, - keepClassNames: true, +const typescriptLoaderConfig = [ + { + test: /\.tsx?$/, + exclude: [/node_modules/], + use: { + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: { + syntax: 'typescript', + tsx: true, }, + keepClassNames: true, }, }, - type: 'javascript/auto', }, - { - test: /\.jsx?$/, - exclude: [/node_modules/], - use: { - loader: 'builtin:swc-loader', - options: { - jsc: { - parser: { - syntax: 'ecmascript', - jsx: true, - }, - transform: { - react: { - pragma: 'React.createElement', - pragmaFrag: 'React.Fragment', - throwIfNamespace: true, - development: isDev, - refresh: isDev, - useBuiltins: false, - }, + type: 'javascript/auto', + }, + { + test: /\.jsx?$/, + exclude: [/node_modules/], + use: { + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: { + syntax: 'ecmascript', + jsx: true, + }, + transform: { + react: { + pragma: 'React.createElement', + pragmaFrag: 'React.Fragment', + throwIfNamespace: true, + development: isDev, + refresh: isDev, + useBuiltins: false, }, - keepClassNames: true, }, + keepClassNames: true, }, }, - type: 'javascript/auto', }, - ] + type: 'javascript/auto', + }, +] const fileLoaderConfig = [ { @@ -144,7 +142,7 @@ const stylesLoaderConfig = [ ] function log(message: string) { - // using errors to avoid screwing up webpack-bundle-analyzer when running with --profile + // using errors to avoid screwing up rspack-bundle-analyzer when running with --profile console.error(message) } @@ -170,7 +168,7 @@ function getConfigEnvironment() { function getPlugins(mode: string, target: string) { const environment = getConfigEnvironment() log( - `Generating bundle for: ${target}\nWebpack running on mode '${mode}' with env var ENVIRONMENT set to: ${environment}` + `Generating bundle for: ${target}\nRspack running on mode '${mode}' with env var ENVIRONMENT set to: ${environment}` ) const plugins = [ diff --git a/packages/botonic-react/package.json b/packages/botonic-react/package.json index 45ba15934d..52e8957985 100644 --- a/packages/botonic-react/package.json +++ b/packages/botonic-react/package.json @@ -1,6 +1,6 @@ { "name": "@botonic/react", - "version": "0.30.5", + "version": "0.30.6", "license": "MIT", "description": "Build Chatbots using React", "main": "./lib/cjs", diff --git a/packages/botonic-react/src/components/element.jsx b/packages/botonic-react/src/components/element.jsx index 54e9dee490..93f71c02a8 100644 --- a/packages/botonic-react/src/components/element.jsx +++ b/packages/botonic-react/src/components/element.jsx @@ -3,6 +3,7 @@ import styled from 'styled-components' import { COLORS, WEBCHAT } from '../constants' import { renderComponent } from '../util/react' +import { Button } from './button' const ElementContainer = styled.div` display: flex; @@ -38,21 +39,13 @@ Element.serialize = elementProps => { ...elementProps.children .filter(c => { if (c instanceof Array) return true - return c && c.type && c.type.name == 'Button' + return c?.type?.name === Button.name }) .map(b => { if (b instanceof Array) { - return b.map( - bb => - bb && - bb.type && - bb.type.serialize && - bb.type.serialize(bb.props).button - ) + b.map(bb => bb?.type?.serialize?.(bb.props)?.button) } - return ( - b && b.type && b.type.serialize && b.type.serialize(b.props).button - ) + return b?.type?.serialize(b.props).button }), ] // When we have the buttons from backend, we have all buttons inside an array on the first position diff --git a/packages/botonic-react/src/components/multichannel/multichannel-button.jsx b/packages/botonic-react/src/components/multichannel/multichannel-button.jsx index 2615db8dce..fc8bb2c326 100644 --- a/packages/botonic-react/src/components/multichannel/multichannel-button.jsx +++ b/packages/botonic-react/src/components/multichannel/multichannel-button.jsx @@ -5,7 +5,7 @@ import { RequestContext } from '../../contexts' import { truncateText } from '../../util' import { Button } from '../button' import { MultichannelContext } from './multichannel-context' -import { WHATSAPP_MAX_BUTTON_CHARS } from './multichannel-utils' +import { WHATSAPP_MAX_BUTTON_CHARS } from './whatsapp/constants' export const MultichannelButton = props => { const requestContext = useContext(RequestContext) diff --git a/packages/botonic-react/src/components/multichannel/multichannel-carousel.jsx b/packages/botonic-react/src/components/multichannel/multichannel-carousel.jsx index 4e3f757b1b..40b3749215 100644 --- a/packages/botonic-react/src/components/multichannel/multichannel-carousel.jsx +++ b/packages/botonic-react/src/components/multichannel/multichannel-carousel.jsx @@ -7,7 +7,9 @@ import { MultichannelText } from './multichannel-text' import { getFilteredElements, isMultichannelButton, - isNodeKind, + isNodePic, + isNodeSubtitle, + isNodeTitle, } from './multichannel-utils' export const MultichannelCarousel = props => { @@ -26,17 +28,17 @@ export const MultichannelCarousel = props => { const buttons = [] for (const node of element) { - if (isNodeKind(node, 'Pic')) { + if (isNodePic(node)) { imageProps = node.props } - if (isNodeKind(node, 'Title')) { + if (isNodeTitle(node)) { title = node.props.children } - if (isNodeKind(node, 'Subtitle')) { + if (isNodeSubtitle(node)) { subtitle = node.props.children } - if (isNodeKind(node, 'MultichannelButton')) { + if (isMultichannelButton(node)) { buttons.push(node) } //TODO support fragment containing an array diff --git a/packages/botonic-react/src/components/multichannel/multichannel-text.jsx b/packages/botonic-react/src/components/multichannel/multichannel-text.jsx index 53f51d6a89..5571e2f834 100644 --- a/packages/botonic-react/src/components/multichannel/multichannel-text.jsx +++ b/packages/botonic-react/src/components/multichannel/multichannel-text.jsx @@ -9,18 +9,20 @@ import { MultichannelButton } from './multichannel-button' import { MultichannelContext } from './multichannel-context' import { buttonTypes, - DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR, elementHasPostback, elementHasUrl, elementHasWebview, getButtonType, getMultichannelButtons, getMultichannelReplies, +} from './multichannel-utils' +import { + DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR, MENU_BUTTON_WHATSAPP_BUTTON_LIST, MULTICHANNEL_WHATSAPP_PROPS, WHATSAPP_LIST_MAX_BUTTONS, WHATSAPP_MAX_BUTTONS, -} from './multichannel-utils' +} from './whatsapp/constants' import { convertToMarkdownMeta } from './whatsapp/markdown-meta' export const MultichannelText = props => { diff --git a/packages/botonic-react/src/components/multichannel/multichannel-utils.js b/packages/botonic-react/src/components/multichannel/multichannel-utils.js index 4b683a5d60..53358b188a 100644 --- a/packages/botonic-react/src/components/multichannel/multichannel-utils.js +++ b/packages/botonic-react/src/components/multichannel/multichannel-utils.js @@ -1,45 +1,63 @@ -/** - * - * Whatsapp does not support Markdown - * (its markup syntax is different) - */ -export const MULTICHANNEL_WHATSAPP_PROPS = { markdown: false } - -export const WHATSAPP_MAX_BUTTONS = 3 -export const WHATSAPP_LIST_MAX_BUTTONS = 10 -export const WHATSAPP_MAX_BUTTON_CHARS = 20 -export const WHATSAPP_MAX_HEADER_CHARS = 60 -export const WHATSAPP_MAX_BODY_CHARS = 1024 -export const WHATSAPP_MAX_FOOTER_CHARS = 60 -export const DEFAULT_WHATSAPP_MAX_BUTTON_SEPARATOR = 'More options:' -export const MENU_BUTTON_WHATSAPP_BUTTON_LIST = 'Show options' +import { Button } from '../button' +import { Carousel } from '../carousel' +import { Pic } from '../pic' +import { Reply } from '../reply' +import { Subtitle } from '../subtitle' +import { Text } from '../text' +import { Title } from '../title' +import { MultichannelButton } from './multichannel-button' +import { MultichannelReply } from './multichannel-reply' + +function isNodeKind(node, kind) { + return node?.type?.name === kind +} export function isMultichannelButton(node) { - return isNodeKind(node, 'MultichannelButton') + return isNodeKind(node, MultichannelButton.name) } export function isMultichannelReply(node) { - return isNodeKind(node, 'MultichannelReply') + return isNodeKind(node, MultichannelReply.name) +} + +export function isNodeText(node) { + return isNodeKind(node, Text.name) +} + +export function isNodeButton(node) { + return isNodeKind(node, Button.name) +} + +export function isNodeCarousel(node) { + return isNodeKind(node, Carousel.name) } -export function isButton(node) { - return isNodeKind(node, 'Button') +export function isNodeReply(node) { + return isNodeKind(node, Reply.name) } -export function isNodeKind(node, kind) { - return node.type && node.type.name == kind +export function isNodePic(node) { + return isNodeKind(node, Pic.name) } + +export function isNodeTitle(node) { + return isNodeKind(node, Title.name) +} + +export function isNodeSubtitle(node) { + return isNodeKind(node, Subtitle.name) +} + export function elementHasUrl(element) { - return element.props && element.props.url + return element?.props?.url } + export function elementHasPostback(element) { - return ( - (element.props && element.props.payload) || - (element.props && element.props.path) - ) + return element?.props?.payload || element?.props?.path } + export function elementHasWebview(element) { - return element.props && element.props.webview + return element?.props?.webview } export const buttonTypes = { diff --git a/packages/botonic-react/src/components/multichannel/multichannel.jsx b/packages/botonic-react/src/components/multichannel/multichannel.jsx index 4f474e963f..c6733a57a3 100644 --- a/packages/botonic-react/src/components/multichannel/multichannel.jsx +++ b/packages/botonic-react/src/components/multichannel/multichannel.jsx @@ -1,7 +1,6 @@ import { isFacebook, isWhatsapp } from '@botonic/core' import React, { useContext } from 'react' -import { COMPONENT_TYPE } from '../../constants' import { RequestContext } from '../../contexts' import { deepMapWithIndex } from '../../util/react' import { Text } from '../text' @@ -10,7 +9,13 @@ import { MultichannelCarousel } from './multichannel-carousel' import { MultichannelContext } from './multichannel-context' import { MultichannelReply } from './multichannel-reply' import { MultichannelText } from './multichannel-text' -import { MULTICHANNEL_WHATSAPP_PROPS } from './multichannel-utils' +import { + isNodeButton, + isNodeCarousel, + isNodeReply, + isNodeText, +} from './multichannel-utils' +import { MULTICHANNEL_WHATSAPP_PROPS } from './whatsapp/constants' export const Multichannel = props => { const requestContext = useContext(RequestContext) @@ -22,7 +27,7 @@ export const Multichannel = props => { } if (isFacebook(requestContext.session)) { const newChildren = deepMapWithIndex(props.children, child => { - if (child && child.type && child.type.name === COMPONENT_TYPE.TEXT) { + if (isNodeText(child)) { return ( {child.props.children} @@ -35,21 +40,21 @@ export const Multichannel = props => { } let newChildren = deepMapWithIndex(props.children, (child, index) => { - if (child && child.type && child.type.name === COMPONENT_TYPE.BUTTON) { + if (isNodeButton(child)) { return ( {child.props.children} ) } - if (child && child.type && child.type.name === COMPONENT_TYPE.REPLY) { + if (isNodeReply(child)) { return ( {child.props.children} ) } - if (child && child.type && child.type.name === COMPONENT_TYPE.TEXT) { + if (isNodeText(child)) { return ( { ) } - if (child && child.type && child.type.name === COMPONENT_TYPE.CAROUSEL) { + if (isNodeCarousel(child)) { return (