New button using default template in kanban view. (#3444)

* New button using default template in kanban view.
This commit is contained in:
Rajat Dabade 2022-08-01 03:39:36 +05:30 committed by GitHub
parent 880a7754f7
commit 04b553621f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 3 deletions

View file

@ -104,6 +104,7 @@ const BoardTemplateSelectorPreview = (props: Props) => {
readonly={false}
onCardClicked={() => null}
addCard={() => Promise.resolve()}
addCardFromTemplate={() => Promise.resolve()}
showCard={() => null}
hiddenCardsCount={0}
showHiddenCardCountNotification={() => null}

View file

@ -68,6 +68,7 @@ const CardDialog = (props: Props): JSX.Element => {
card.fields.isTemplate,
intl.formatMessage({id: 'Mutator.new-template-from-card', defaultMessage: 'new template from card'}),
true,
{},
async (newCardId) => {
props.showCard(newCardId)
},

View file

@ -258,8 +258,17 @@ const CenterPanel = (props: Props) => {
}
}, [selectedCardIds])
const addCardFromTemplate = useCallback(async (cardTemplateId: string) => {
const {activeView, board} = props
const addCardFromTemplate = useCallback(async (cardTemplateId: string, groupByOptionId?: string) => {
const {activeView, board, groupByProperty} = props
const propertiesThatMeetFilters = CardFilter.propertiesThatMeetFilterGroup(activeView.fields.filter, board.cardProperties)
if ((activeView.fields.viewType === 'board' || activeView.fields.viewType === 'table') && groupByProperty) {
if (groupByOptionId) {
propertiesThatMeetFilters[groupByProperty.id] = groupByOptionId
} else {
delete propertiesThatMeetFilters[groupByProperty.id]
}
}
mutator.performAsUndoGroup(async () => {
const [, newCardId] = await mutator.duplicateCard(
@ -268,6 +277,7 @@ const CenterPanel = (props: Props) => {
true,
intl.formatMessage({id: 'Mutator.new-card-from-template', defaultMessage: 'new card from template'}),
false,
propertiesThatMeetFilters,
async (cardId) => {
dispatch(updateView({...activeView, fields: {...activeView.fields, cardOrder: [...activeView.fields.cardOrder, cardId]}}))
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateCardViaTemplate, {board: props.board.id, view: props.activeView.id, card: cardId, cardTemplateId})
@ -421,6 +431,7 @@ const CenterPanel = (props: Props) => {
readonly={props.readonly}
onCardClicked={cardClicked}
addCard={addCard}
addCardFromTemplate={addCardFromTemplate}
showCard={showCard}
hiddenCardsCount={props.hiddenCardsCount}
showHiddenCardCountNotification={hiddenCardCountNotifyHandler}

View file

@ -88,6 +88,12 @@ describe('src/component/kanban/kanban', () => {
board_id_1: {userId: 'user_id_1', schemeAdmin: true},
},
},
views: {
views: {
boardView: activeView,
},
current: 'boardView',
},
contents: {},
comments: {
comments: {},
@ -126,6 +132,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -162,6 +169,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -197,6 +205,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -234,6 +243,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -281,6 +291,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -328,6 +339,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -376,6 +388,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={mockedAddCard}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -415,6 +428,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -454,6 +468,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -500,6 +515,7 @@ describe('src/component/kanban/kanban', () => {
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={jest.fn()}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
@ -514,3 +530,128 @@ describe('src/component/kanban/kanban', () => {
})
})
})
describe('src/component/kanban/kanban', () => {
const board = TestBlockFactory.createBoard()
const activeView = TestBlockFactory.createBoardView(board)
const card1 = TestBlockFactory.createCard(board)
card1.id = 'id1'
card1.fields.properties = {id: 'property_value_id_1'}
const card2 = TestBlockFactory.createCard(board)
card2.id = 'id2'
card2.fields.properties = {id: 'property_value_id_1'}
const card3 = TestBlockFactory.createCard(board)
card3.id = 'id3'
card3.fields.properties = {id: 'property_value_id_2'}
activeView.fields.kanbanCalculations = {
id1: {
calculation: 'countEmpty',
propertyId: '1',
},
}
activeView.fields.defaultTemplateId = "defaultTemplateId"
const optionQ1:IPropertyOption = {
color: 'propColorOrange',
id: 'property_value_id_1',
value: 'Q1',
}
const optionQ2:IPropertyOption = {
color: 'propColorBlue',
id: 'property_value_id_2',
value: 'Q2',
}
const optionQ3:IPropertyOption = {
color: 'propColorDefault',
id: 'property_value_id_3',
value: 'Q3',
}
const groupProperty: IPropertyTemplate = {
id: 'id',
name: 'name',
type: 'text',
options: [optionQ1, optionQ2],
}
const state = {
users: {
me: {
id: 'user_id_1',
props: {},
},
},
cards: {
cards: [card1, card2, card3],
},
teams: {
current: {id: 'team-id'},
},
boards: {
current: 'board_id_1',
boards: {
board_id_1: {id: 'board_id_1'},
},
myBoardMemberships: {
board_id_1: {userId: 'user_id_1', schemeAdmin: true},
},
},
views: {
views: {
boardView: activeView,
},
current: 'boardView',
},
contents: {},
comments: {
comments: {},
},
}
const store = mockStateStore([], state)
beforeAll(() => {
console.error = jest.fn()
mockDOM()
})
beforeEach(jest.resetAllMocks)
test('return kanban and click on New if view have already have defaultTemplateId', () => {
const mockedAddCard = jest.fn()
render(wrapDNDIntl(
<ReduxProvider store={store}>
<Kanban
board={board}
activeView={activeView}
cards={[card1, card2]}
groupByProperty={groupProperty}
visibleGroups={[
{
option: optionQ1,
cards: [card1, card2],
}, {
option: optionQ2,
cards: [card3],
},
]}
hiddenGroups={[
{
option: optionQ3,
cards: [],
},
]}
selectedCardIds={[]}
readonly={false}
onCardClicked={jest.fn()}
addCard={jest.fn()}
addCardFromTemplate={mockedAddCard}
showCard={jest.fn()}
hiddenCardsCount={0}
showHiddenCardCountNotification={jest.fn()}
/>
</ReduxProvider>,
), {wrapper: MemoryRouter})
const allButtonsNew = screen.getAllByRole('button', {name: '+ New'})
expect(allButtonsNew).not.toBeNull()
userEvent.click(allButtonsNew[0])
expect(mockedAddCard).toBeCalledTimes(1)
})
})

View file

@ -6,6 +6,9 @@ import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'
import withScrolling, {createHorizontalStrength, createVerticalStrength} from 'react-dnd-scrolling'
import {useAppSelector} from '../../store/hooks'
import {getCurrentView} from '../../store/views'
import {Position} from '../cardDetail/cardDetailContents'
import {Board, IPropertyOption, IPropertyTemplate, BoardGroup} from '../../blocks/board'
@ -40,6 +43,7 @@ type Props = {
readonly: boolean
onCardClicked: (e: React.MouseEvent, card: Card) => void
addCard: (groupByOptionId?: string, show?:boolean) => Promise<void>
addCardFromTemplate: (cardTemplateId: string, groupByOptionId?: string) => void
showCard: (cardId?: string) => void
hiddenCardsCount: number
showHiddenCardCountNotification: (show: boolean) => void
@ -50,6 +54,7 @@ const hStrength = createHorizontalStrength(Utils.isMobile() ? 60 : 250)
const vStrength = createVerticalStrength(Utils.isMobile() ? 60 : 250)
const Kanban = (props: Props) => {
const currentView = useAppSelector(getCurrentView)
const {board, activeView, cards, groupByProperty, visibleGroups, hiddenGroups, hiddenCardsCount} = props
if (!groupByProperty) {
@ -292,7 +297,11 @@ const Kanban = (props: Props) => {
<BoardPermissionGate permissions={[Permission.ManageBoardCards]}>
<Button
onClick={() => {
props.addCard(group.option.id, true)
if(currentView.fields.defaultTemplateId) {
props.addCardFromTemplate(currentView.fields.defaultTemplateId, group.option.id)
} else {
props.addCard(group.option.id, true)
}
}}
>
<FormattedMessage

View file

@ -115,6 +115,7 @@ const KanbanCard = (props: Props) => {
false,
'duplicate card',
false,
{},
async (newCardId) => {
props.showCard(newCardId)
},

View file

@ -975,6 +975,7 @@ class Mutator {
fromTemplate = false,
description = 'duplicate card',
asTemplate = false,
propertyOverrides?: Record<string, string>,
afterRedo?: (newCardId: string) => Promise<void>,
beforeUndo?: () => Promise<void>,
): Promise<[Block[], string]> {
@ -1004,6 +1005,7 @@ class Mutator {
const patch = {
updatedFields: {
icon: newRootBlock.fields.icon,
properties: {...newRootBlock.fields.properties, ...propertyOverrides}
},
title: newRootBlock.title,
}