Skip to content

Commit

Permalink
MM-58502 Error on crossing block limit on client side (#5015)
Browse files Browse the repository at this point in the history
* refactor: error on crossing block limit

* fix: linter

* chore: updated snapshot

* refactor: updated mysql/mysql-server docker version

* chore: changed blob to text.length
  • Loading branch information
Rajat-Dabade authored Aug 7, 2024
1 parent 568a5f0 commit 1932acb
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docker-testing/docker-compose-mysql.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '2.4'
services:
mysql:
image: "mysql/mysql-server:5.7.12"
image: "mysql/mysql-server:8.0.32"
restart: always
environment:
MYSQL_ROOT_HOST: "%"
Expand Down
1 change: 1 addition & 0 deletions webapp/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
"ContentBlock.editCardCheckboxText": "edit card text",
"ContentBlock.editCardText": "edit card text",
"ContentBlock.editText": "Edit text...",
"ContentBlock.errorText": "You've exceeded the size limit for this content. Please shorten it to avoid losing data.",
"ContentBlock.image": "image",
"ContentBlock.insertAbove": "Insert above",
"ContentBlock.moveBlock": "move card content",
Expand Down
13 changes: 12 additions & 1 deletion webapp/package-lock.json

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

1 change: 1 addition & 0 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@mattermost/compass-icons": "^0.1.39",
"@reduxjs/toolkit": "^1.8.0",
"@tippyjs/react": "4.2.6",
"classnames": "^2.5.1",
"color": "^4.2.1",
"draft-js": "^0.11.7",
"emoji-mart": "^3.0.1",
Expand Down
12 changes: 8 additions & 4 deletions webapp/src/components/__snapshots__/contentBlock.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,16 @@ exports[`components/contentBlock should match snapshot with textBlock 1`] = `
style="flex: 0 0 auto; height: 100%;"
/>
<div
class="MarkdownEditor octo-editor "
class="TextElement"
>
<div
class="octo-editor-preview"
data-testid="preview-element"
/>
class="MarkdownEditor octo-editor "
>
<div
class="octo-editor-preview"
data-testid="preview-element"
/>
</div>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
exports[`components/content/TextElement return a textElement 1`] = `
<div>
<div
class="MarkdownEditor octo-editor "
class="TextElement"
>
<div
class="octo-editor-preview octo-placeholder"
data-testid="preview-element"
/>
class="MarkdownEditor octo-editor "
>
<div
class="octo-editor-preview octo-placeholder"
data-testid="preview-element"
/>
</div>
</div>
</div>
`;
13 changes: 13 additions & 0 deletions webapp/src/components/content/textElement.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.TextElement {
display: inline;

.markdown-editor-error {
background-color: rgba(210, 75, 78, 0.08);
border: 1px solid var(--error-text);
}

.error-message {
color: var(--dnd-indicator, rgba(210, 75, 78, 1));
margin: 16px 0;
}
}
54 changes: 41 additions & 13 deletions webapp/src/components/content/textElement.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import React, {useState} from 'react'
import {useIntl} from 'react-intl'

import cx from 'classnames'

import {ContentBlock} from '../../blocks/contentBlock'
import {createTextBlock} from '../../blocks/textBlock'
import mutator from '../../mutator'
Expand All @@ -11,26 +13,52 @@ import {MarkdownEditor} from '../markdownEditor'

import {contentRegistry} from './contentRegistry'

import './textElement.scss'

type Props = {
block: ContentBlock
readonly: boolean
}

const TextElement = (props: Props): JSX.Element => {
const {block, readonly} = props
const BlockTitleMaxBytes = 65535 // Maximum size of a TEXT column in MySQL
const BlockTitleMaxRunes = BlockTitleMaxBytes / 4 // Assume a worst-case representation

const TextElement = ({block, readonly}: Props): JSX.Element => {
const intl = useIntl()

const [isError, setIsError] = useState<boolean>(false)
const [blockTitle, setBlockTitle] = useState(block.title)

const textChangedHandler = (text: string): void => {
setBlockTitle(text)
const textSize = text.length
setIsError(textSize > BlockTitleMaxRunes)
}

const handleBlur = (text: string): void => {
if (text !== block.title || blockTitle !== block.title) {
const textSize = new Blob([text]).size
if (textSize <= BlockTitleMaxRunes) {
mutator.changeBlockTitle(block.boardId, block.id, block.title, text, intl.formatMessage({id: 'ContentBlock.editCardText', defaultMessage: 'edit card text'})).
finally(() => {
setIsError(false)
})
}
}
}

return (
<MarkdownEditor
text={block.title}
placeholderText={intl.formatMessage({id: 'ContentBlock.editText', defaultMessage: 'Edit text...'})}
onBlur={(text) => {
if (text !== block.title) {
mutator.changeBlockTitle(block.boardId, block.id, block.title, text, intl.formatMessage({id: 'ContentBlock.editCardText', defaultMessage: 'edit card text'}))
}
}}
readonly={readonly}
/>
<div className='TextElement'>
<MarkdownEditor
className={cx({'markdown-editor-error': isError})}
text={blockTitle}
placeholderText={intl.formatMessage({id: 'ContentBlock.editText', defaultMessage: 'Edit text...'})}
onChange={textChangedHandler}
onBlur={handleBlur}
readonly={readonly}
/>
{isError && <div className='error-message'>{intl.formatMessage({id: 'ContentBlock.errorText', defaultMessage: 'You\'ve exceeded the size limit for this content. Please shorten it to avoid losing data.'})}</div>}
</div>
)
}

Expand Down

0 comments on commit 1932acb

Please sign in to comment.