// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React from 'react' import {FormattedMessage, injectIntl, IntlShape} from 'react-intl' import mutator from '../mutator' import {OctoListener} from '../octoListener' import {Utils} from '../utils' import {BoardTree} from '../viewModel/boardTree' import {CardTree, MutableCardTree} from '../viewModel/cardTree' import DeleteIcon from '../widgets/icons/delete' import Menu from '../widgets/menu' import CardDetail from './cardDetail' import Dialog from './dialog' type Props = { boardTree: BoardTree cardId: string onClose: () => void showCard: (cardId?: string) => void intl: IntlShape readonly: boolean } type State = { cardTree?: CardTree, syncComplete: boolean } class CardDialog extends React.Component { state: State = {syncComplete: false} private cardListener?: OctoListener shouldComponentUpdate(): boolean { return true } componentDidMount(): void { this.createCardTreeAndSync() } private async createCardTreeAndSync() { const cardTree = await MutableCardTree.sync(this.props.cardId) this.createListener() this.setState({cardTree, syncComplete: true}) Utils.log(`cardDialog.createCardTreeAndSync: ${cardTree?.card.id}`) } private createListener() { this.deleteListener() this.cardListener = new OctoListener() this.cardListener.open( [this.props.cardId], async (blocks) => { Utils.log(`cardListener.onChanged: ${blocks.length}`) const newCardTree = this.state.cardTree ? MutableCardTree.incrementalUpdate(this.state.cardTree, blocks) : await MutableCardTree.sync(this.props.cardId) this.setState({cardTree: newCardTree, syncComplete: true}) }, async () => { Utils.log('cardListener.onReconnect') const newCardTree = await MutableCardTree.sync(this.props.cardId) this.setState({cardTree: newCardTree, syncComplete: true}) }, ) } private deleteListener() { this.cardListener?.close() this.cardListener = undefined } componentWillUnmount(): void { this.deleteListener() } render(): JSX.Element { const {cardTree} = this.state const menu = ( } name='Delete' onClick={async () => { const card = this.state.cardTree?.card if (!card) { Utils.assertFailure() return } await mutator.deleteBlock(card, 'delete card') this.props.onClose() }} /> {(cardTree && !cardTree.card.isTemplate) && } ) return ( {(cardTree?.card.isTemplate) &&
} {this.state.cardTree && } {(!this.state.cardTree && this.state.syncComplete) &&
}
) } private makeTemplateClicked = async () => { const {cardTree} = this.state if (!cardTree) { Utils.assertFailure('this.state.cardTree') return } await mutator.duplicateCard( cardTree.card.id, this.props.intl.formatMessage({id: 'Mutator.new-template-from-card', defaultMessage: 'new template from card'}), true, async (newCardId) => { this.props.showCard(newCardId) }, async () => { this.props.showCard(undefined) }, ) } } export default injectIntl(CardDialog)