Fix GH-1690: Default card template on a board template adds a card to the template, not the board (#1748)

This commit is contained in:
Hossein 2021-11-09 17:11:22 -05:00 committed by GitHub
parent cfbec9d90b
commit c13371c648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 4 deletions

View file

@ -598,6 +598,7 @@ exports[`src/components/workspace return workspace and showcard 1`] = `
class="KanbanCalculation"
>
<button
title="3"
type="button"
>
<span>
@ -651,6 +652,7 @@ exports[`src/components/workspace return workspace and showcard 1`] = `
class="KanbanCalculation"
>
<button
title="0"
type="button"
>
<span>
@ -1120,6 +1122,7 @@ exports[`src/components/workspace return workspace readonly and showcard 1`] = `
class="KanbanCalculation"
>
<button
title="3"
type="button"
>
<span>
@ -1152,6 +1155,7 @@ exports[`src/components/workspace return workspace readonly and showcard 1`] = `
class="KanbanCalculation"
>
<button
title="0"
type="button"
>
<span>
@ -1887,6 +1891,7 @@ exports[`src/components/workspace should match snapshot 1`] = `
class="KanbanCalculation"
>
<button
title="3"
type="button"
>
<span>
@ -1940,6 +1945,7 @@ exports[`src/components/workspace should match snapshot 1`] = `
class="KanbanCalculation"
>
<button
title="0"
type="button"
>
<span>
@ -2409,6 +2415,7 @@ exports[`src/components/workspace should match snapshot with readonly 1`] = `
class="KanbanCalculation"
>
<button
title="3"
type="button"
>
<span>
@ -2441,6 +2448,7 @@ exports[`src/components/workspace should match snapshot with readonly 1`] = `
class="KanbanCalculation"
>
<button
title="0"
type="button"
>
<span>

View file

@ -48,6 +48,7 @@ const CardDialog = (props: Props): JSX.Element => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.AddTemplateFromCard, {board: props.board.id, view: activeView.id, card: props.cardId})
await mutator.duplicateCard(
props.cardId,
board,
intl.formatMessage({id: 'Mutator.new-template-from-card', defaultMessage: 'new template from card'}),
true,
async (newCardId) => {

View file

@ -211,11 +211,12 @@ class CenterPanel extends React.Component<Props, State> {
}
private addCardFromTemplate = async (cardTemplateId: string) => {
const {activeView} = this.props
const {activeView, board} = this.props
mutator.performAsUndoGroup(async () => {
const [, newCardId] = await mutator.duplicateCard(
cardTemplateId,
board,
this.props.intl.formatMessage({id: 'Mutator.new-card-from-template', defaultMessage: 'new card from template'}),
false,
async (cardId) => {
@ -361,6 +362,7 @@ class CenterPanel extends React.Component<Props, State> {
}
private async duplicateSelectedCards() {
const {board} = this.props
const {selectedCardIds} = this.state
if (selectedCardIds.length < 1) {
return
@ -370,7 +372,7 @@ class CenterPanel extends React.Component<Props, State> {
for (const cardId of selectedCardIds) {
const card = this.props.cards.find((o) => o.id === cardId)
if (card) {
mutator.duplicateCard(cardId)
mutator.duplicateCard(cardId, board)
} else {
Utils.assertFailure(`Selected card not found: ${cardId}`)
}

View file

@ -162,7 +162,7 @@ describe('src/components/gallery/GalleryCard', () => {
userEvent.click(buttonDuplicate)
expect(container).toMatchSnapshot()
expect(mockedMutator.duplicateCard).toBeCalledTimes(1)
expect(mockedMutator.duplicateCard).toBeCalledWith(card.id)
expect(mockedMutator.duplicateCard).toBeCalledWith(card.id, board)
})
test('return GalleryCard and copy link', () => {
const {container} = render(wrapDNDIntl(

View file

@ -93,7 +93,7 @@ const GalleryCard = React.memo((props: Props) => {
name={intl.formatMessage({id: 'GalleryCard.duplicate', defaultMessage: 'Duplicate'})}
onClick={() => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateCard, {board: board.id, card: card.id})
mutator.duplicateCard(card.id)
mutator.duplicateCard(card.id, board)
}}
/>
<Menu.Text

View file

@ -78,6 +78,7 @@ const KanbanCard = React.memo((props: Props) => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateCard, {board: board.id, card: card.id})
mutator.duplicateCard(
card.id,
board,
'duplicate card',
false,
async (newCardId) => {

View file

@ -32,4 +32,23 @@ describe('Mutator', () => {
// 1 API call should be made as property value DID CHANGE
expect(FetchMock.fn).toBeCalledTimes(1)
})
test('duplicateCard', async () => {
const card = TestBlockFactory.createCard()
const board = TestBlockFactory.createBoard()
FetchMock.fn.mockReturnValueOnce(FetchMock.jsonResponse(JSON.stringify([card])))
FetchMock.fn.mockReturnValueOnce(FetchMock.jsonResponse(JSON.stringify({})))
const [newBlocks, newCardID] = await mutator.duplicateCard(card.id, board)
expect(newBlocks).toHaveLength(1)
const duplicatedCard = newBlocks[0]
expect(duplicatedCard.type).toBe('card')
expect(duplicatedCard.id).toBe(newCardID)
expect(duplicatedCard.fields.icon).toBe(card.fields.icon)
expect(duplicatedCard.fields.contentOrder).toHaveLength(card.fields.contentOrder.length)
expect(duplicatedCard.parentId).toBe(board.id)
expect(duplicatedCard.rootId).toBe(board.id)
})
})

View file

@ -636,6 +636,7 @@ class Mutator {
async duplicateCard(
cardId: string,
board: Board,
description = 'duplicate card',
asTemplate = false,
afterRedo?: (newCardId: string) => Promise<void>,
@ -661,6 +662,8 @@ class Mutator {
}
}
newCard.fields.isTemplate = asTemplate
newCard.rootId = board.id
newCard.parentId = board.id
await this.insertBlocks(
newBlocks,
description,