mirror of
https://github.com/mattermost/focalboard.git
synced 2024-11-27 08:31:20 +02:00
Put shown cardId in url, to allow direct linking to cards
This commit is contained in:
parent
8f441747dd
commit
cd9e34499b
@ -72,6 +72,7 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.showCardInUrl()
|
||||
document.addEventListener('keydown', this.keydownHandler)
|
||||
}
|
||||
|
||||
@ -99,6 +100,14 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
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 {boardTree, showView} = this.props
|
||||
const {groupByProperty} = boardTree
|
||||
@ -129,8 +138,8 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
key={this.state.shownCardId}
|
||||
boardTree={boardTree}
|
||||
cardId={this.state.shownCardId}
|
||||
onClose={() => this.setState({shownCardId: undefined})}
|
||||
showCard={(cardId) => this.setState({shownCardId: cardId})}
|
||||
onClose={() => this.showCard(undefined)}
|
||||
showCard={(cardId) => this.showCard(cardId)}
|
||||
/>
|
||||
</RootPortal>}
|
||||
|
||||
@ -482,10 +491,10 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
this.props.intl.formatMessage({id: 'Mutator.new-card-from-template', defaultMessage: 'new card from template'}),
|
||||
false,
|
||||
async (newCardId) => {
|
||||
this.setState({shownCardId: newCardId})
|
||||
this.showCard(newCardId)
|
||||
},
|
||||
async () => {
|
||||
this.setState({shownCardId: undefined})
|
||||
this.showCard(undefined)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -514,10 +523,10 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
card,
|
||||
'add card',
|
||||
async () => {
|
||||
this.setState({shownCardId: card.id})
|
||||
this.showCard(card.id)
|
||||
},
|
||||
async () => {
|
||||
this.setState({shownCardId: undefined})
|
||||
this.showCard(undefined)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -533,15 +542,15 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
cardTemplate,
|
||||
'add card template',
|
||||
async () => {
|
||||
this.setState({shownCardId: cardTemplate.id})
|
||||
this.showCard(cardTemplate.id)
|
||||
}, async () => {
|
||||
this.setState({shownCardId: undefined})
|
||||
this.showCard(undefined)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private editCardTemplate = (cardTemplateId: string) => {
|
||||
this.setState({shownCardId: cardTemplateId})
|
||||
this.showCard(cardTemplateId)
|
||||
}
|
||||
|
||||
private async propertyNameChanged(option: IPropertyOption, text: string): Promise<void> {
|
||||
@ -577,12 +586,17 @@ class BoardComponent extends React.Component<Props, State> {
|
||||
this.setState({selectedCardIds})
|
||||
}
|
||||
} else {
|
||||
this.setState({selectedCardIds: [], shownCardId: card.id})
|
||||
this.showCard(card.id)
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
private showCard = (cardId?: string) => {
|
||||
Utils.replaceUrlQueryParam('c', cardId)
|
||||
this.setState({selectedCardIds: [], shownCardId: cardId})
|
||||
}
|
||||
|
||||
private addGroupClicked = async () => {
|
||||
Utils.log('onAddGroupClicked')
|
||||
|
||||
|
@ -45,6 +45,18 @@ class TableComponent extends React.Component<Props, State> {
|
||||
return true
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.showCardInUrl()
|
||||
}
|
||||
|
||||
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 {boardTree, showView} = this.props
|
||||
const {board, cards, activeView} = boardTree
|
||||
@ -66,8 +78,8 @@ class TableComponent extends React.Component<Props, State> {
|
||||
key={this.state.shownCardId}
|
||||
boardTree={boardTree}
|
||||
cardId={this.state.shownCardId}
|
||||
onClose={() => this.setState({shownCardId: undefined})}
|
||||
showCard={(cardId) => this.setState({shownCardId: cardId})}
|
||||
onClose={() => this.showCard(undefined)}
|
||||
showCard={(cardId) => this.showCard(cardId)}
|
||||
/>
|
||||
</RootPortal>}
|
||||
<div className='octo-frame'>
|
||||
@ -263,9 +275,7 @@ class TableComponent extends React.Component<Props, State> {
|
||||
this.addCard(false)
|
||||
}
|
||||
}}
|
||||
showCard={(cardId) => {
|
||||
this.setState({shownCardId: cardId})
|
||||
}}
|
||||
showCard={this.showCard}
|
||||
/>)
|
||||
|
||||
this.cardIdToRowMap.set(card.id, tableRowRef)
|
||||
@ -295,6 +305,11 @@ class TableComponent extends React.Component<Props, State> {
|
||||
)
|
||||
}
|
||||
|
||||
private showCard = (cardId?: string) => {
|
||||
Utils.replaceUrlQueryParam('c', cardId)
|
||||
this.setState({shownCardId: cardId})
|
||||
}
|
||||
|
||||
private columnWidth(templateId: string): number {
|
||||
return Math.max(Constants.minColumnWidth, this.props.boardTree.activeView.columnWidths[templateId] || 0)
|
||||
}
|
||||
@ -309,10 +324,10 @@ class TableComponent extends React.Component<Props, State> {
|
||||
this.props.intl.formatMessage({id: 'Mutator.new-card-from-template', defaultMessage: 'new card from template'}),
|
||||
false,
|
||||
async (newCardId) => {
|
||||
this.setState({shownCardId: newCardId})
|
||||
this.showCard(newCardId)
|
||||
},
|
||||
async () => {
|
||||
this.setState({shownCardId: undefined})
|
||||
this.showCard(undefined)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -332,7 +347,7 @@ class TableComponent extends React.Component<Props, State> {
|
||||
'add card',
|
||||
async () => {
|
||||
if (show) {
|
||||
this.setState({shownCardId: card.id})
|
||||
this.showCard(card.id)
|
||||
} else {
|
||||
// Focus on this card's title inline on next render
|
||||
this.cardIdToFocusOnRender = card.id
|
||||
@ -352,15 +367,15 @@ class TableComponent extends React.Component<Props, State> {
|
||||
cardTemplate,
|
||||
'add card template',
|
||||
async () => {
|
||||
this.setState({shownCardId: cardTemplate.id})
|
||||
this.showCard(cardTemplate.id)
|
||||
}, async () => {
|
||||
this.setState({shownCardId: undefined})
|
||||
this.showCard(undefined)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private editCardTemplate = (cardTemplateId: string) => {
|
||||
this.setState({shownCardId: cardTemplateId})
|
||||
this.showCard(cardTemplateId)
|
||||
}
|
||||
|
||||
private async onDropToColumn(template: IPropertyTemplate) {
|
||||
|
@ -131,6 +131,22 @@ class Utils {
|
||||
document.getElementsByTagName('head')[0].appendChild(link)
|
||||
}
|
||||
|
||||
// URL
|
||||
|
||||
static replaceUrlQueryParam(paramName: string, value?: string): void {
|
||||
const queryString = new URLSearchParams(window.location.search)
|
||||
const currentValue = queryString.get(paramName) || ''
|
||||
if (currentValue !== value) {
|
||||
const newUrl = new URL(window.location.toString())
|
||||
if (value) {
|
||||
newUrl.searchParams.set(paramName, value)
|
||||
} else {
|
||||
newUrl.searchParams.delete(paramName)
|
||||
}
|
||||
window.history.pushState({}, document.title, newUrl.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// File names
|
||||
|
||||
static sanitizeFilename(filename: string): string {
|
||||
|
Loading…
Reference in New Issue
Block a user