Skip to content

Commit

Permalink
Merge pull request #52 from ML-Leonardo/fix/custom_json_issues
Browse files Browse the repository at this point in the history
Fixed issue where trying to do a map on a undefined element.  (Possib…
  • Loading branch information
JWandrocke authored and GitHub Enterprise committed May 27, 2020
2 parents 0990224 + 925f4ec commit f889826
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/components/Message/Buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'

import Button from 'components/Button'

import { truncate } from 'helpers'
import { truncate, safeArrayOfItem } from 'helpers'

import './style.scss'

Expand All @@ -16,7 +16,7 @@ const Buttons = ({ content, sendMessage, style, readOnlyMode }) => {
</p>

<div className='Buttons--container'>
{buttons.slice(0, 3).map((b, i) => (
{safeArrayOfItem(buttons).slice(0, 3).map((b, i) => (
<Button
key={i}
button={b}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Message/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
import { sanitizeUrl } from '@braintree/sanitize-url'

import { truncate } from 'helpers'
import { truncate, safeArrayOfItem } from 'helpers'

import Button from 'components/Button'

Expand All @@ -25,7 +25,7 @@ const Card = ({ content, sendMessage, onImageLoaded, readOnlyMode }) => {

{buttons && buttons.length ? (
<div className='RecastAppCard--button-container CaiAppCard--button-container'>
{buttons.slice(0, 3).map((b, i) => (
{safeArrayOfItem(buttons).slice(0, 3).map((b, i) => (
<Button
key={i}
button={b}
Expand Down
3 changes: 2 additions & 1 deletion src/components/Message/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Slider from 'react-slick'

import Card from './Card'
import { PrevArrow, NextArrow } from 'components/arrows'
import { safeArrayOfItem } from 'helpers'

import './style.scss'

Expand All @@ -22,7 +23,7 @@ const Carousel = ({ content, sendMessage, readOnlyMode }) => {
slidesToScroll={1}
className='Slider'
>
{content.map((card, i) => (
{safeArrayOfItem(content).map((card, i) => (
<div key={i}>
<Card content={card} sendMessage={sendMessage} readOnlyMode={readOnlyMode} />
</div>
Expand Down
7 changes: 4 additions & 3 deletions src/components/Message/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { sanitizeUrl } from '@braintree/sanitize-url'
import propOr from 'ramda/es/propOr'
import cx from 'classnames'

import { truncate } from 'helpers'
import { truncate, safeArrayOfItem } from 'helpers'

import Button from 'components/Button'

Expand Down Expand Up @@ -111,11 +111,12 @@ ListElement.propTypes = {
}

const List = ({ content, sendMessage, readOnlyMode }) => {
const button = content.buttons && content.buttons[0]
const { buttons } = content
const button = propOr(null, 0, buttons)

return (
<div className={'RecastAppList CaiAppList'}>
{content.elements.map((element, i) => (
{safeArrayOfItem(content && content.elements).map((element, i) => (
<ListElement
key={i} {...element}
sendMessage={sendMessage}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Message/QuickReplies.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import map from 'ramda/es/map'
import values from 'ramda/es/values'
import cx from 'classnames'

import { truncate } from 'helpers'
import { truncate, safeArrayOfItem } from 'helpers'

import Text from './Text'
import { PrevArrow, NextArrow } from 'components/arrows'
Expand Down Expand Up @@ -79,7 +79,7 @@ class QuickReplies extends Component {
nextArrow={<NextArrow />}
className='RecastAppSlider RecastAppQuickReplies--slider CaiAppSlider CaiAppQuickReplies--slider'
>
{buttons.map((b, i) => (
{safeArrayOfItem(buttons).map((b, i) => (
<div key={i}>
<div
ref={ref => {
Expand Down
16 changes: 2 additions & 14 deletions src/components/Message/Text.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import sanitizeHtml from 'sanitize-html-react'
import ReactMarkdown from 'react-markdown'
import cx from 'classnames'

import { truncate } from 'helpers'
import { truncate, safeStringValue } from 'helpers'

import './style.scss'

Expand All @@ -31,24 +31,12 @@ const allowedMarkdownTypes = [
]

const Text = ({ content, style, isMarkdown, readOnlyMode }) => {
let respond
const respond = safeStringValue(content)

if (typeof isMarkdown !== 'boolean') {
isMarkdown = false
}

if (typeof content === 'string') {
respond = content
} else if (typeof content === 'object') {
respond = JSON.stringify(content)
} else if (typeof content === 'number') {
respond = content.toString()
} else if (content === undefined) {
respond = 'undefined'
} else {
respond = ''
}

let maxLengthLimit = 640
// JIRA: https://sapjira.wdf.sap.corp/browse/SAPMLCONV-4904
if (isMarkdown) {
Expand Down
37 changes: 33 additions & 4 deletions src/components/Message/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import cx from 'classnames'
import contains from 'ramda/es/contains'
import { safeBooleanValue } from 'helpers'

import Text from './Text'
import Card from './Card'
Expand All @@ -14,6 +15,15 @@ import QuickReplies from './QuickReplies'
import './style.scss'

class Message extends Component {
state = {
exceptionThrownOccurred: false,
}

componentDidCatch (error, info) {
this.setState({ exceptionThrownOccurred: true })
console.error(error, info)
}

render () {
const {
message,
Expand All @@ -37,16 +47,35 @@ class Message extends Component {
botMessageColor,
botMessageBackgroundColor,
} = preferences
const { displayIcon } = message
const { type, content, error, title, markdown } = message.attachment
const isBot = message.participant.isBot
const { displayIcon, attachment, participant } = message
const { type, content, error, title, markdown } = attachment
const { exceptionThrownOccurred } = this.state
if (exceptionThrownOccurred) {
const style = {
color: '#fff',
backgroundColor: '#f44336',
padding: '1.0rem',
textAlign: 'center',
}

return (
<div style={style} className={'RecastAppText CaiAppText'}>
An Error has occured, unable to display this message
</div>
)
}
if (!content) {
console.error('Missing content unable to proceed')
return null
}
const { isBot } = participant

const image = isBot ? botPicture : userPicture
const messageProps = {
isBot,
// Make sure we display the title of a button/quickReply click, and not its value
content: title || content,
isMarkdown: markdown,
isMarkdown: safeBooleanValue(markdown),
readOnlyMode,
onImageLoaded,
style: {
Expand Down
43 changes: 39 additions & 4 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@

export const truncate = (string, length) => {
if (string.length <= length) {
return string
}
// console.assert(typeof string === 'string', `Expected a 'string', but got a type:'${typeof string}' - '${string}'`)
if (typeof string === 'string') {
if (string.length <= length) {
return string
}

return `${string.slice(0, length - 3)}...`
return `${string.slice(0, length - 3)}...`
}
return ''
}

const conversationKey = 'cai-conversation'
Expand Down Expand Up @@ -41,3 +45,34 @@ export const getCredentialsFromLocalStorage = () => {
}
return null
}

export const safeArrayOfItem = (items) => {
console.assert(items && Array.isArray(items), `Expected a array of items, but got a type:'${typeof items}'`)
if (items && Array.isArray(items)) {
return items
}
return []
}

export const safeBooleanValue = (flag) => {
if (typeof flag === 'boolean') {
return flag
} else if (typeof flag === 'string') {
return flag.toLowerCase() === 'true'
}
return false
}

export const safeStringValue = (content) => {
if (typeof content === 'string') {
return content
} else if (typeof content === 'object') {
return JSON.stringify(content)
} else if (typeof content === 'number') {
return content.toString()
} else if (content === undefined) {
return 'undefined'
}
return ''
}

Loading

0 comments on commit f889826

Please sign in to comment.