mirror of
https://github.com/mattermost/focalboard.git
synced 2025-03-11 14:09:34 +02:00
Fixing some things
This commit is contained in:
parent
dd82913e39
commit
dbfde1a238
@ -1,14 +1,17 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useEffect} from 'react'
|
||||
import React, {useEffect, useCallback} from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {IntlProvider} from 'react-intl'
|
||||
import {IntlProvider, useIntl} from 'react-intl'
|
||||
import {DndProvider} from 'react-dnd'
|
||||
import {HTML5Backend} from 'react-dnd-html5-backend'
|
||||
import {TouchBackend} from 'react-dnd-touch-backend'
|
||||
|
||||
import store from '../../../webapp/src/store'
|
||||
import {updateCards, getRHSCardID, getRHSCard, getRHSBoardID} from '../../../webapp/src/store/cards'
|
||||
import {getRHSCard, getRHSBoardID} from '../../../webapp/src/store/cards'
|
||||
import {getCardAttachments} from '../../../webapp/src/store/attachments'
|
||||
import mutator from '../../../webapp/src/mutator'
|
||||
|
||||
import {getBoard} from '../../../webapp/src/store/boards'
|
||||
import {Block} from '../../../webapp/src/blocks/block'
|
||||
import {fetchMe, getMe} from '../../../webapp/src/store/users'
|
||||
@ -20,11 +23,10 @@ import {loadBoardData} from '../../../webapp/src/store/initialLoad'
|
||||
import {useAppSelector} from '../../../webapp/src/store/hooks'
|
||||
import {getMessages} from '../../../webapp/src/i18n'
|
||||
import CardDetail from '../../../webapp/src/components/cardDetail/cardDetail'
|
||||
import {sendFlashMessage} from '../../../webapp/src/components/flashMessages'
|
||||
import useConnectToBoard from '../../../webapp/src/hooks/connectToBoard'
|
||||
import {Utils} from '../../../webapp/src/utils'
|
||||
|
||||
import octoClient from '../../../webapp/src/octoClient'
|
||||
|
||||
import '../../../webapp/src/styles/variables.scss'
|
||||
import '../../../webapp/src/styles/main.scss'
|
||||
import '../../../webapp/src/styles/labels.scss'
|
||||
@ -40,8 +42,9 @@ const RHSCardContent = () => {
|
||||
const views = useAppSelector(getViewsByBoard)
|
||||
const comments = useAppSelector(getCardComments(card?.id))
|
||||
const contents = useAppSelector(getCardContents(card?.id))
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
const activeView = views[boardID] && views[boardID][0]
|
||||
const attachments = useAppSelector(getCardAttachments(card.id))
|
||||
const intl = useIntl()
|
||||
|
||||
useEffect(() => {
|
||||
if (boardID) {
|
||||
@ -51,34 +54,63 @@ const RHSCardContent = () => {
|
||||
}
|
||||
}, [boardID])
|
||||
|
||||
const deleteBlock = useCallback(async (block: Block) => {
|
||||
if (!card) {
|
||||
return
|
||||
}
|
||||
const description = intl.formatMessage({id: 'AttachmentBlock.DeleteAction', defaultMessage: 'delete'})
|
||||
await mutator.deleteBlock(block, description)
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.delete', defaultMessage: 'Attachment Deleted Successfully.'}), severity: 'normal'})
|
||||
}, [card?.boardId, card?.id, card?.fields.contentOrder])
|
||||
|
||||
// TODO: Check the permissions here
|
||||
const readonly = false
|
||||
|
||||
useConnectToBoard(store.dispatch, '', me?.id || '', boardID || '', Boolean(readonly), boardID || '')
|
||||
useConnectToBoard(store.dispatch, me?.id || '', boardID || '', Boolean(readonly), boardID || '')
|
||||
|
||||
if (!board || !card || !activeView) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<CardDetail
|
||||
board={board}
|
||||
activeView={activeView}
|
||||
views={views[boardID]}
|
||||
cards={[]}
|
||||
card={card}
|
||||
comments={comments}
|
||||
contents={contents}
|
||||
readonly={readonly}
|
||||
attachments={attachments}
|
||||
onDelete={deleteBlock}
|
||||
addAttachment={() => {}}
|
||||
onClose={() => {}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const RHSCardWithIntl = () => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<CardDetail
|
||||
board={board}
|
||||
activeView={activeView}
|
||||
views={views[boardID]}
|
||||
cards={[]}
|
||||
card={card}
|
||||
comments={comments}
|
||||
contents={contents}
|
||||
readonly={readonly}
|
||||
attachments={[]}
|
||||
onDelete={() => {}}
|
||||
onClose={() => {}}
|
||||
addAttachment={() => {}}
|
||||
/>
|
||||
<div
|
||||
className='focalboard-body RHSCard'
|
||||
onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
onKeyPress={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
onKeyUp={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
>
|
||||
{/* TODO: Remove this hack to avoid the capture of the cursor by the create post component */}
|
||||
<div
|
||||
className='channel-switch-modal'
|
||||
style={{display: 'none'}}
|
||||
/>
|
||||
<RHSCardContent/>
|
||||
</div>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
@ -87,19 +119,7 @@ const RHSCard = () => {
|
||||
return (
|
||||
<ReduxProvider store={store}>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<div
|
||||
className='focalboard-body RHSCard'
|
||||
onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
onKeyPress={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
onKeyUp={(e: React.KeyboardEvent) => e.stopPropagation()}
|
||||
>
|
||||
{/* TODO: Remove this hack to avoid the capture of the cursor by the create post component */}
|
||||
<div
|
||||
className='channel-switch-modal'
|
||||
style={{display: 'none'}}
|
||||
/>
|
||||
<RHSCardContent/>
|
||||
</div>
|
||||
<RHSCardWithIntl/>
|
||||
</DndProvider>
|
||||
</ReduxProvider>
|
||||
)
|
||||
|
@ -1,87 +1,89 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {useEffect, useState} from 'react'
|
||||
import {useMemo} from 'react'
|
||||
import {batch} from 'react-redux'
|
||||
|
||||
import {Block} from '../blocks/block'
|
||||
import {ContentBlock} from '../blocks/contentBlock'
|
||||
import {AttachmentBlock} from '../blocks/attachmentBlock'
|
||||
import {Utils} from '../utils'
|
||||
import {CommentBlock} from '../blocks/commentBlock'
|
||||
import {Board} from '../blocks/board'
|
||||
import {Board, BoardMember} from '../blocks/board'
|
||||
import {Card} from '../blocks/card'
|
||||
import {BoardView} from '../blocks/boardView'
|
||||
|
||||
import wsClient, {Subscription, WSClient} from '../wsclient'
|
||||
import {updateBoards} from '../store/boards'
|
||||
import {Subscription, WSClient} from '../wsclient'
|
||||
import {
|
||||
updateBoards,
|
||||
updateMembersEnsuringBoardsAndUsers,
|
||||
fetchBoardMembers,
|
||||
addMyBoardMemberships,
|
||||
} from '../store/boards'
|
||||
import {updateViews} from '../store/views'
|
||||
import {updateCards} from '../store/cards'
|
||||
import {updateContents} from '../store/contents'
|
||||
import {updateComments} from '../store/comments'
|
||||
import {updateAttachments} from '../store/attachments'
|
||||
import {followBlock, unfollowBlock} from '../store/users'
|
||||
import {initialLoad, initialReadOnlyLoad} from '../store/initialLoad'
|
||||
import {Constants} from '../constants'
|
||||
|
||||
const websocketTimeoutForBanner = 5000
|
||||
import {useWebsockets} from './websockets'
|
||||
|
||||
export default function useConnectToBoard(dispatch: any, readToken: string, myID: string, teamId: string|undefined, readonly: boolean, boardId: string): void {
|
||||
const [websocketClosed, setWebsocketClosed] = useState(false)
|
||||
useEffect(() => {
|
||||
let loadAction: any = initialLoad /* eslint-disable-line @typescript-eslint/no-explicit-any */
|
||||
let token = localStorage.getItem('focalboardSessionId') || ''
|
||||
export default function useConnectToBoard(dispatch: any, myID: string, teamId: string, readonly: boolean, boardId: string): void {
|
||||
const loadAction: (boardId: string) => any = useMemo(() => {
|
||||
if (readonly) {
|
||||
loadAction = initialReadOnlyLoad
|
||||
token = token || readToken || ''
|
||||
return initialReadOnlyLoad
|
||||
}
|
||||
return initialLoad
|
||||
}, [readonly])
|
||||
|
||||
dispatch(loadAction(boardId))
|
||||
useWebsockets(teamId, (wsClient: WSClient) =>{
|
||||
const incrementalBlockUpdate = (_: WSClient, blocks: Block[]) => {
|
||||
const teamBlocks = blocks
|
||||
|
||||
let subscribedToTeam = false
|
||||
if (wsClient.state === 'open') {
|
||||
wsClient.authenticate(token)
|
||||
wsClient.subscribeToTeam(teamId || '0')
|
||||
subscribedToTeam = true
|
||||
}
|
||||
|
||||
const incrementalUpdateBoard = (_: WSClient, boards: Board[]) => {
|
||||
// only takes into account the boards that belong to the team
|
||||
const teamBoards = boards.filter((b: Board) => b.teamId === '0' || b.teamId === teamId)
|
||||
dispatch(updateBoards(teamBoards.filter((b: Board) => b.deleteAt !== 0)))
|
||||
}
|
||||
|
||||
const incrementalUpdateBlock = (_: WSClient, blocks: Block[]) => {
|
||||
batch(() => {
|
||||
dispatch(updateViews(blocks.filter((b: Block) => b.type === 'view' || b.deleteAt !== 0) as BoardView[]))
|
||||
dispatch(updateCards(blocks.filter((b: Block) => b.type === 'card' || b.deleteAt !== 0) as Card[]))
|
||||
dispatch(updateComments(blocks.filter((b: Block) => b.type === 'comment' || b.deleteAt !== 0) as CommentBlock[]))
|
||||
dispatch(updateContents(blocks.filter((b: Block) => b.type !== 'card' && b.type !== 'view' && b.type !== 'board' && b.type !== 'comment') as ContentBlock[]))
|
||||
dispatch(updateViews(teamBlocks.filter((b: Block) => b.type === 'view' || b.deleteAt !== 0) as BoardView[]))
|
||||
dispatch(updateCards(teamBlocks.filter((b: Block) => b.type === 'card' || b.deleteAt !== 0) as Card[]))
|
||||
dispatch(updateComments(teamBlocks.filter((b: Block) => b.type === 'comment' || b.deleteAt !== 0) as CommentBlock[]))
|
||||
dispatch(updateAttachments(teamBlocks.filter((b: Block) => b.type === 'attachment' || b.deleteAt !== 0) as AttachmentBlock[]))
|
||||
dispatch(updateContents(teamBlocks.filter((b: Block) => b.type !== 'card' && b.type !== 'view' && b.type !== 'board' && b.type !== 'comment' && b.type !== 'attachment') as ContentBlock[]))
|
||||
})
|
||||
}
|
||||
|
||||
let timeout: ReturnType<typeof setTimeout>
|
||||
const updateWebsocketState = (_: WSClient, newState: 'init'|'open'|'close'): void => {
|
||||
if (newState === 'open') {
|
||||
const newToken = localStorage.getItem('focalboardSessionId') || ''
|
||||
wsClient.authenticate(newToken)
|
||||
wsClient.subscribeToTeam(teamId || '0')
|
||||
subscribedToTeam = true
|
||||
}
|
||||
const incrementalBoardUpdate = (_: WSClient, boards: Board[]) => {
|
||||
// only takes into account the entities that belong to the team or the user boards
|
||||
const teamBoards = boards.filter((b: Board) => b.teamId === Constants.globalTeamId || b.teamId === teamId)
|
||||
const activeBoard = teamBoards.find((b: Board) => b.id === boardId)
|
||||
dispatch(updateBoards(teamBoards))
|
||||
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
|
||||
if (newState === 'close') {
|
||||
timeout = setTimeout(() => {
|
||||
setWebsocketClosed(true)
|
||||
subscribedToTeam = false
|
||||
}, websocketTimeoutForBanner)
|
||||
} else {
|
||||
setWebsocketClosed(false)
|
||||
if (activeBoard) {
|
||||
dispatch(fetchBoardMembers({
|
||||
teamId,
|
||||
boardId: boardId,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
wsClient.addOnChange(incrementalUpdateBoard, 'board')
|
||||
wsClient.addOnChange(incrementalUpdateBlock, 'block')
|
||||
wsClient.addOnReconnect(() => dispatch(loadAction(boardId)))
|
||||
wsClient.addOnStateChange(updateWebsocketState)
|
||||
const incrementalBoardMemberUpdate = (_: WSClient, members: BoardMember[]) => {
|
||||
dispatch(updateMembersEnsuringBoardsAndUsers(members))
|
||||
|
||||
if (myID) {
|
||||
const myBoardMemberships = members.filter((boardMember) => boardMember.userId === myID)
|
||||
dispatch(addMyBoardMemberships(myBoardMemberships))
|
||||
}
|
||||
}
|
||||
|
||||
const dispatchLoadAction = () => {
|
||||
dispatch(loadAction(boardId))
|
||||
}
|
||||
|
||||
Utils.log('useWEbsocket adding onChange handler')
|
||||
wsClient.addOnChange(incrementalBlockUpdate, 'block')
|
||||
wsClient.addOnChange(incrementalBoardUpdate, 'board')
|
||||
wsClient.addOnChange(incrementalBoardMemberUpdate, 'boardMembers')
|
||||
wsClient.addOnReconnect(dispatchLoadAction)
|
||||
|
||||
wsClient.setOnFollowBlock((_: WSClient, subscription: Subscription): void => {
|
||||
if (subscription.subscriberId === myID) {
|
||||
dispatch(followBlock(subscription))
|
||||
@ -92,17 +94,13 @@ export default function useConnectToBoard(dispatch: any, readToken: string, myID
|
||||
dispatch(unfollowBlock(subscription))
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
if (subscribedToTeam) {
|
||||
wsClient.unsubscribeToTeam(teamId || '0')
|
||||
}
|
||||
wsClient.removeOnChange(incrementalUpdateBlock, 'block')
|
||||
wsClient.removeOnChange(incrementalUpdateBoard, 'board')
|
||||
wsClient.removeOnReconnect(() => dispatch(loadAction(boardId)))
|
||||
wsClient.removeOnStateChange(updateWebsocketState)
|
||||
Utils.log('useWebsocket cleanup')
|
||||
wsClient.removeOnChange(incrementalBlockUpdate, 'block')
|
||||
wsClient.removeOnChange(incrementalBoardUpdate, 'board')
|
||||
wsClient.removeOnChange(incrementalBoardMemberUpdate, 'boardMembers')
|
||||
wsClient.removeOnReconnect(dispatchLoadAction)
|
||||
}
|
||||
}, [teamId, readonly, boardId, myID])
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user