diff --git a/webapp/src/app.tsx b/webapp/src/app.tsx
index ac56a4bc8..18165db2b 100644
--- a/webapp/src/app.tsx
+++ b/webapp/src/app.tsx
@@ -78,7 +78,7 @@ const App = React.memo((): JSX.Element => {
-
+
{loggedIn === false && }
{loggedIn === true && }
@@ -86,7 +86,7 @@ const App = React.memo((): JSX.Element => {
{
if (loggedIn === false) {
let redirectUrl = '/' + Utils.buildURL(`/workspace/${match.params.workspaceId}/`)
@@ -109,7 +109,7 @@ const App = React.memo((): JSX.Element => {
>
-
+
{loggedIn === false && }
{loggedIn === true && }
diff --git a/webapp/src/components/centerPanel.tsx b/webapp/src/components/centerPanel.tsx
index 64387e692..5505c0a69 100644
--- a/webapp/src/components/centerPanel.tsx
+++ b/webapp/src/components/centerPanel.tsx
@@ -37,10 +37,11 @@ type Props = {
readonly: boolean
addCard: (card: Card) => void
addTemplate: (template: Card) => void
+ shownCardId?: string
+ showCard: (cardId?: string) => void
}
type State = {
- shownCardId?: string
selectedCardIds: string[]
cardIdToFocusOnRender: string
}
@@ -77,10 +78,6 @@ class CenterPanel extends React.Component {
}
}
- componentDidMount(): void {
- this.showCardInUrl()
- }
-
constructor(props: Props) {
super(props)
this.state = {
@@ -93,14 +90,6 @@ class CenterPanel extends React.Component {
return true
}
- private showCardInUrl() {
- const queryString = new URLSearchParams(window.location.search)
- const cardId = queryString.get('c') || undefined
- if (cardId !== this.state.shownCardId) {
- this.setState({shownCardId: cardId})
- }
- }
-
render(): JSX.Element {
const {groupByProperty, activeView, board, views, cards} = this.props
const {visible: visibleGroups, hidden: hiddenGroups} = this.getVisibleAndHiddenGroups(cards, activeView.fields.visibleOptionIds, activeView.fields.hiddenOptionIds, groupByProperty)
@@ -117,15 +106,15 @@ class CenterPanel extends React.Component {
keyName='ctrl+d,del,esc,backspace'
onKeyDown={this.keydownHandler}
/>
- {this.state.shownCardId &&
+ {this.props.shownCardId &&
this.showCard(undefined)}
showCard={(cardId) => this.showCard(cardId)}
readonly={this.props.readonly}
@@ -316,8 +305,8 @@ class CenterPanel extends React.Component {
}
private showCard = (cardId?: string) => {
- Utils.replaceUrlQueryParam('c', cardId)
- this.setState({selectedCardIds: [], shownCardId: cardId})
+ this.setState({selectedCardIds: []})
+ this.props.showCard(cardId)
}
private async deleteSelectedCards() {
diff --git a/webapp/src/components/workspace.tsx b/webapp/src/components/workspace.tsx
index ed4b81f6a..08788002b 100644
--- a/webapp/src/components/workspace.tsx
+++ b/webapp/src/components/workspace.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react'
-import {useRouteMatch} from 'react-router-dom'
+import React, {useCallback} from 'react'
+import {generatePath, useRouteMatch, useHistory} from 'react-router-dom'
import {FormattedMessage} from 'react-intl'
import {getCurrentBoard} from '../store/boards'
@@ -19,12 +19,19 @@ type Props = {
}
function CenterContent(props: Props) {
- const match = useRouteMatch<{boardId: string, viewId: string}>()
+ const match = useRouteMatch<{boardId: string, viewId: string, cardId?: string}>()
const board = useAppSelector(getCurrentBoard)
const cards = useAppSelector(getCurrentViewCardsSortedFilteredAndGrouped)
const activeView = useAppSelector(getView(match.params.viewId))
const views = useAppSelector(getCurrentBoardViews)
const groupByProperty = useAppSelector(getCurrentViewGroupBy)
+ const history = useHistory()
+
+ const showCard = useCallback((cardId?: string) => {
+ const params = {...match.params, cardId}
+ const newPath = generatePath(match.path, params)
+ history.push(newPath)
+ }, [match, history])
if (board && activeView) {
let property = groupByProperty
@@ -36,6 +43,8 @@ function CenterContent(props: Props) {
readonly={props.readonly}
board={board}
cards={cards}
+ shownCardId={match.params.cardId}
+ showCard={showCard}
activeView={activeView}
groupByProperty={property}
views={views}
diff --git a/webapp/src/pages/boardPage.tsx b/webapp/src/pages/boardPage.tsx
index 37cfd6bf6..6622afb0a 100644
--- a/webapp/src/pages/boardPage.tsx
+++ b/webapp/src/pages/boardPage.tsx
@@ -42,7 +42,7 @@ const BoardPage = (props: Props) => {
const dispatch = useAppDispatch()
const history = useHistory()
- const match = useRouteMatch<{boardId: string, viewId: string, workspaceId?: string}>()
+ const match = useRouteMatch<{boardId: string, viewId: string, cardId?: string, workspaceId?: string}>()
const [websocketClosed, setWebsocketClosed] = useState(false)
// TODO: Make this less brittle. This only works because this is the root render function
@@ -53,20 +53,37 @@ const BoardPage = (props: Props) => {
// Backward compatibility: This can be removed in the future, this is for
// transform the old query params into routes
useEffect(() => {
- const queryString = new URLSearchParams(window.location.search)
- const queryBoardId = queryString.get('id')
- const queryViewId = queryString.get('v')
- if (queryBoardId) {
- const params = {...match.params, boardId: queryBoardId}
- if (queryViewId) {
- params.viewId = queryViewId
- }
- const newPath = generatePath(match.path, params)
- history.replace(newPath)
- }
}, [])
useEffect(() => {
+ // Backward compatibility: This can be removed in the future, this is for
+ // transform the old query params into routes
+ const queryString = new URLSearchParams(history.location.search)
+ const queryBoardId = queryString.get('id')
+ const params = {...match.params}
+ let needsRedirect = false
+ if (queryBoardId) {
+ params.boardId = queryBoardId
+ needsRedirect = true
+ }
+ const queryViewId = queryString.get('v')
+ if (queryViewId) {
+ params.viewId = queryViewId
+ needsRedirect = true
+ }
+ const queryCardId = queryString.get('c')
+ if (queryCardId) {
+ params.cardId = queryCardId
+ needsRedirect = true
+ }
+ if (needsRedirect) {
+ const newPath = generatePath(match.path, params)
+ history.replace(newPath)
+ return
+ }
+
+ // Backward compatibility end
+
const boardId = match.params.boardId
const viewId = match.params.viewId
@@ -96,7 +113,7 @@ const BoardPage = (props: Props) => {
UserSettings.lastViewId = viewId || ''
dispatch(setCurrentBoard(boardId || ''))
dispatch(setCurrentView(viewId || ''))
- }, [match.params.boardId, match.params.viewId, history, boardViews])
+ }, [match.params.boardId, match.params.viewId, boardViews])
useEffect(() => {
Utils.setFavicon(board?.fields.icon)
@@ -119,7 +136,7 @@ const BoardPage = (props: Props) => {
let token = localStorage.getItem('focalboardSessionId') || ''
if (props.readonly) {
loadAction = initialReadOnlyLoad
- const queryString = new URLSearchParams(window.location.search)
+ const queryString = new URLSearchParams(history.location.search)
token = token || queryString.get('r') || ''
}
dispatch(loadAction(match.params.boardId))