1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-11-27 08:31:20 +02:00

Update telemetry (#1673)

This commit is contained in:
Chen-I Lim 2021-10-27 09:30:42 -07:00 committed by GitHub
parent 902a25c265
commit 380bd92725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 95 additions and 61 deletions

View File

@ -2,8 +2,6 @@
// See LICENSE.txt for license information.
import {Utils, IDType} from '../utils'
import TelemetryClient, {TelemetryCategory, TelemetryActions} from '../telemetry/telemetryClient'
import {Block, createBlock} from './block'
import {Card} from './card'
@ -60,7 +58,6 @@ function createBoard(block?: Block): Board {
}
})
}
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoard, {isTemplate: block?.fields.isTemplate || false})
return {
...createBlock(block),

View File

@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import TelemetryClient, {TelemetryCategory, TelemetryActions} from '../telemetry/telemetryClient'
import {Block, createBlock} from './block'
import {FilterGroup, createFilterGroup} from './filterGroup'
@ -35,7 +33,6 @@ type BoardView = Block & {
}
function createBoardView(block?: Block): BoardView {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoardView, {viewType: block?.fields.viewType || 'board'})
return {
...createBlock(block),
type: 'view',

View File

@ -58,7 +58,7 @@ const CardDetail = (props: Props): JSX.Element|null => {
if (!title) {
titleRef.current?.focus()
}
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewCard, {card: card.id})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewCard, {board: props.board.id, view: props.activeView.id, card: card.id})
}, [])
useEffect(() => {

View File

@ -3,20 +3,20 @@
import React from 'react'
import {FormattedMessage, useIntl} from 'react-intl'
import mutator from '../mutator'
import {Utils} from '../utils'
import {BoardView} from '../blocks/boardView'
import {Board} from '../blocks/board'
import {BoardView} from '../blocks/boardView'
import {Card} from '../blocks/card'
import mutator from '../mutator'
import {getCard} from '../store/cards'
import {getCardComments} from '../store/comments'
import {getCardContents} from '../store/contents'
import {useAppSelector} from '../store/hooks'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../telemetry/telemetryClient'
import {Utils} from '../utils'
import DeleteIcon from '../widgets/icons/delete'
import LinkIcon from '../widgets/icons/Link'
import Menu from '../widgets/menu'
import {useAppSelector} from '../store/hooks'
import {getCard} from '../store/cards'
import {getCardContents} from '../store/contents'
import {getCardComments} from '../store/comments'
import CardDetail from './cardDetail/cardDetail'
import Dialog from './dialog'
import {sendFlashMessage} from './flashMessages'
@ -45,6 +45,7 @@ const CardDialog = (props: Props): JSX.Element => {
return
}
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.AddTemplateFromCard, {board: props.board.id, view: activeView.id, card: card.id})
await mutator.duplicateCard(
props.cardId,
intl.formatMessage({id: 'Mutator.new-template-from-card', defaultMessage: 'new template from card'}),
@ -69,6 +70,7 @@ const CardDialog = (props: Props): JSX.Element => {
Utils.assertFailure()
return
}
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DeleteCard, {board: props.board.id, view: props.activeView.id, card: card.id})
await mutator.deleteBlock(card, 'delete card')
props.onClose()
}}

View File

@ -84,7 +84,7 @@ class CenterPanel extends React.Component<Props, State> {
}
componentDidMount(): void {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewBoard, {viewType: this.props.activeView.fields.viewType})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewBoard, {board: this.props.board.id, view: this.props.activeView.id, viewType: this.props.activeView.fields.viewType})
}
constructor(props: Props) {
@ -100,7 +100,7 @@ class CenterPanel extends React.Component<Props, State> {
}
componentDidUpdate(): void {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewBoard, {viewType: this.props.activeView.fields.viewType})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewBoard, {board: this.props.board.id, view: this.props.activeView.id, viewType: this.props.activeView.fields.viewType})
}
render(): JSX.Element {
@ -211,6 +211,7 @@ class CenterPanel extends React.Component<Props, State> {
private addCardFromTemplate = async (cardTemplateId: string) => {
const {activeView} = this.props
mutator.performAsUndoGroup(async () => {
const [, newCardId] = await mutator.duplicateCard(
cardTemplateId,
@ -218,6 +219,7 @@ class CenterPanel extends React.Component<Props, State> {
false,
async (cardId) => {
this.props.updateView({...activeView, fields: {...activeView.fields, cardOrder: [...activeView.fields.cardOrder, cardId]}})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateCardViaTemplate, {board: this.props.board.id, view: this.props.activeView.id, card: cardId, cardTemplateId})
this.showCard(cardId)
},
async () => {
@ -233,6 +235,8 @@ class CenterPanel extends React.Component<Props, State> {
const card = createCard()
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateCard, {board: board.id, view: this.props.activeView.id, card: card.id})
card.parentId = board.id
card.rootId = board.rootId
const propertiesThatMeetFilters = CardFilter.propertiesThatMeetFilterGroup(activeView.fields.filter, board.fields.cardProperties)
@ -277,10 +281,12 @@ class CenterPanel extends React.Component<Props, State> {
cardTemplate.fields.isTemplate = true
cardTemplate.parentId = board.id
cardTemplate.rootId = board.rootId
await mutator.insertBlock(
cardTemplate,
'add card template',
async () => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateCardTemplate, {board: board.id, view: this.props.activeView.id, card: cardTemplate.id})
this.props.addTemplate(cardTemplate)
this.showCard(cardTemplate.id)
}, async () => {

View File

@ -6,29 +6,27 @@ import {FormattedMessage, useIntl} from 'react-intl'
import {Board, IPropertyTemplate} from '../../blocks/board'
import {Card} from '../../blocks/card'
import {ContentBlock} from '../../blocks/contentBlock'
import {useSortable} from '../../hooks/sortable'
import mutator from '../../mutator'
import {getCardComments} from '../../store/comments'
import {getCardContents} from '../../store/contents'
import {useAppSelector} from '../../store/hooks'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../../telemetry/telemetryClient'
import {Utils} from '../../utils'
import IconButton from '../../widgets/buttons/iconButton'
import DeleteIcon from '../../widgets/icons/delete'
import DuplicateIcon from '../../widgets/icons/duplicate'
import OptionsIcon from '../../widgets/icons/options'
import LinkIcon from '../../widgets/icons/Link'
import OptionsIcon from '../../widgets/icons/options'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {useSortable} from '../../hooks/sortable'
import ImageElement from '../content/imageElement'
import ContentElement from '../content/contentElement'
import PropertyValueElement from '../propertyValueElement'
import {sendFlashMessage} from '../flashMessages'
import Tooltip from '../../widgets/tooltip'
import {useAppSelector} from '../../store/hooks'
import {getCardContents} from '../../store/contents'
import {getCardComments} from '../../store/comments'
import './galleryCard.scss'
import {CardDetailProvider} from '../cardDetail/cardDetailContext'
import ContentElement from '../content/contentElement'
import ImageElement from '../content/imageElement'
import {sendFlashMessage} from '../flashMessages'
import PropertyValueElement from '../propertyValueElement'
import './galleryCard.scss'
type Props = {
board: Board
@ -94,6 +92,7 @@ const GalleryCard = React.memo((props: Props) => {
id='duplicate'
name={intl.formatMessage({id: 'GalleryCard.duplicate', defaultMessage: 'Duplicate'})}
onClick={() => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateCard, {board: props.board.id, card: card.id})
mutator.duplicateCard(card.id)
}}
/>

View File

@ -5,24 +5,24 @@ import {useIntl} from 'react-intl'
import {Board, IPropertyTemplate} from '../../blocks/board'
import {Card} from '../../blocks/card'
import {useSortable} from '../../hooks/sortable'
import mutator from '../../mutator'
import {getCardComments} from '../../store/comments'
import {getCardContents} from '../../store/contents'
import {useAppSelector} from '../../store/hooks'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../../telemetry/telemetryClient'
import {Utils} from '../../utils'
import IconButton from '../../widgets/buttons/iconButton'
import DeleteIcon from '../../widgets/icons/delete'
import DuplicateIcon from '../../widgets/icons/duplicate'
import OptionsIcon from '../../widgets/icons/options'
import LinkIcon from '../../widgets/icons/Link'
import OptionsIcon from '../../widgets/icons/options'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {useSortable} from '../../hooks/sortable'
import {Utils} from '../../utils'
import {sendFlashMessage} from '../flashMessages'
import {useAppSelector} from '../../store/hooks'
import {getCardContents} from '../../store/contents'
import {getCardComments} from '../../store/comments'
import './kanbanCard.scss'
import PropertyValueElement from '../propertyValueElement'
import Tooltip from '../../widgets/tooltip'
import {sendFlashMessage} from '../flashMessages'
import PropertyValueElement from '../propertyValueElement'
import './kanbanCard.scss'
type Props = {
card: Card
@ -75,6 +75,7 @@ const KanbanCard = React.memo((props: Props) => {
id='duplicate'
name={intl.formatMessage({id: 'KanbanCard.duplicate', defaultMessage: 'Duplicate'})}
onClick={() => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateCard, {board: props.board.id, card: card.id})
mutator.duplicateCard(
card.id,
'duplicate card',

View File

@ -49,7 +49,7 @@ const ShareBoardComponent = React.memo((props: Props): JSX.Element => {
const newSharing: ISharing = sharing || createSharingInfo()
newSharing.id = props.boardId
newSharing.enabled = isOn
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ShareBoard, {board: props.boardId, enabled: isOn})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ShareBoard, {board: props.boardId, shareBoardEnabled: isOn})
await client.setSharing(newSharing)
await loadData()
}

View File

@ -1,23 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useEffect, useCallback} from 'react'
import {FormattedMessage, useIntl, IntlShape} from 'react-intl'
import React, {useCallback, useEffect} from 'react'
import {FormattedMessage, IntlShape, useIntl} from 'react-intl'
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
import {Board, createBoard} from '../../blocks/board'
import {createBoardView} from '../../blocks/boardView'
import mutator from '../../mutator'
import octoClient from '../../octoClient'
import {getSortedTemplates} from '../../store/boards'
import {fetchGlobalTemplates, getGlobalTemplates} from '../../store/globalTemplates'
import {useAppDispatch, useAppSelector} from '../../store/hooks'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../../telemetry/telemetryClient'
import AddIcon from '../../widgets/icons/add'
import BoardIcon from '../../widgets/icons/board'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {useAppDispatch, useAppSelector} from '../../store/hooks'
import {getGlobalTemplates, fetchGlobalTemplates} from '../../store/globalTemplates'
import {getSortedTemplates} from '../../store/boards'
import BoardTemplateMenuItem from './boardTemplateMenuItem'
import './sidebarAddBoardMenu.scss'
type Props = {
@ -40,6 +40,7 @@ export const addBoardClicked = async (showBoard: (id: string) => void, intl: Int
[board, view],
'add board',
async () => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoard, {board: board.id})
showBoard(board.id)
},
async () => {
@ -66,6 +67,7 @@ export const addBoardTemplateClicked = async (showBoard: (id: string) => void, i
[boardTemplate, view],
'add board template',
async () => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoardTemplate, {board: boardTemplate.id})
showBoard(boardTemplate.id)
}, async () => {
if (activeBoardId) {

View File

@ -1,23 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useState, useCallback} from 'react'
import React, {useCallback, useState} from 'react'
import {FormattedMessage, useIntl} from 'react-intl'
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
import {Board} from '../../blocks/board'
import {BoardView, IViewType, sortBoardViewsAlphabetically} from '../../blocks/boardView'
import mutator from '../../mutator'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../../telemetry/telemetryClient'
import IconButton from '../../widgets/buttons/iconButton'
import BoardIcon from '../../widgets/icons/board'
import DeleteIcon from '../../widgets/icons/delete'
import DisclosureTriangle from '../../widgets/icons/disclosureTriangle'
import DuplicateIcon from '../../widgets/icons/duplicate'
import GalleryIcon from '../../widgets/icons/gallery'
import OptionsIcon from '../../widgets/icons/options'
import TableIcon from '../../widgets/icons/table'
import GalleryIcon from '../../widgets/icons/gallery'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import './sidebarBoardItem.scss'
type Props = {
@ -86,6 +86,7 @@ const SidebarBoardItem = React.memo((props: Props) => {
intl.formatMessage({id: 'Mutator.new-template-from-board', defaultMessage: 'new template from board'}),
true,
async (newBoardId) => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.AddTemplateFromBoard, {board: newBoardId})
showBoard(newBoardId)
},
async () => {
@ -124,6 +125,7 @@ const SidebarBoardItem = React.memo((props: Props) => {
name={intl.formatMessage({id: 'Sidebar.delete-board', defaultMessage: 'Delete board'})}
icon={<DeleteIcon/>}
onClick={async () => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DeleteBoard, {board: board.id})
mutator.deleteBlock(
board,
intl.formatMessage({id: 'Sidebar.delete-board', defaultMessage: 'Delete board'}),
@ -147,6 +149,7 @@ const SidebarBoardItem = React.memo((props: Props) => {
name={intl.formatMessage({id: 'Sidebar.duplicate-board', defaultMessage: 'Duplicate board'})}
icon={<DuplicateIcon/>}
onClick={() => {
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateBoard, {board: board.id})
duplicateBoard(board.id || '')
}}
/>

View File

@ -5,16 +5,17 @@ import {injectIntl, IntlShape} from 'react-intl'
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
import {Board, IPropertyTemplate} from '../blocks/board'
import {IViewType, BoardView, createBoardView} from '../blocks/boardView'
import {BoardView, createBoardView, IViewType} from '../blocks/boardView'
import {Constants} from '../constants'
import mutator from '../mutator'
import {Utils, IDType} from '../utils'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../telemetry/telemetryClient'
import {IDType, Utils} from '../utils'
import AddIcon from '../widgets/icons/add'
import BoardIcon from '../widgets/icons/board'
import DeleteIcon from '../widgets/icons/delete'
import DuplicateIcon from '../widgets/icons/duplicate'
import TableIcon from '../widgets/icons/table'
import GalleryIcon from '../widgets/icons/gallery'
import TableIcon from '../widgets/icons/table'
import Menu from '../widgets/menu'
type Props = {
@ -40,6 +41,7 @@ const ViewMenu = React.memo((props: Props) => {
const handleDuplicateView = useCallback(() => {
const {activeView} = props
Utils.log('duplicateView')
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DuplicateBoardView, {board: props.board.id, view: activeView.id})
const currentViewId = activeView.id
const newView = createBoardView(activeView)
newView.title = `${activeView.title} copy`
@ -62,6 +64,7 @@ const ViewMenu = React.memo((props: Props) => {
const handleDeleteView = useCallback(() => {
const {activeView, views} = props
Utils.log('deleteView')
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.DeleteBoardView, {board: props.board.id, view: activeView.id})
const view = activeView
const nextView = views.find((o) => o !== view)
mutator.deleteBlock(view, 'delete view')
@ -83,6 +86,7 @@ const ViewMenu = React.memo((props: Props) => {
const handleAddViewBoard = useCallback(() => {
const {board, activeView, intl} = props
Utils.log('addview-board')
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoardView, {board: props.board.id, view: activeView.id})
const view = createBoardView()
view.title = intl.formatMessage({id: 'View.NewBoardTitle', defaultMessage: 'Board view'})
view.fields.viewType = 'board'

View File

@ -409,7 +409,7 @@ class Mutator {
delete newCard.fields.properties[propertyId]
}
await this.updateBlock(newCard, card, description)
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.EditCardProperty, {card: card.id})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.EditCardProperty, {board: card.rootId, card: card.id})
}
async changePropertyTypeAndName(board: Board, cards: Card[], propertyTemplate: IPropertyTemplate, newType: PropertyType, newName: string) {

View File

@ -169,7 +169,7 @@ const BoardPage = (props: Props): JSX.Element => {
if (props.readonly) {
loadAction = initialReadOnlyLoad
token = token || queryString.get('r') || ''
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewSharedBoard, {board: board.id})
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ViewSharedBoard, {board: board.id, view: activeView.id})
}
dispatch(loadAction(match.params.boardId))

View File

@ -8,16 +8,39 @@ export const TelemetryCategory = 'boards'
export const TelemetryActions = {
ClickChannelHeader: 'clickChannelHeader',
CreateBoard: 'createBoard',
CreateBoardViaTemplate: 'createBoardViaTemplate',
CreateBoardView: 'createBoardView',
EditCardProperty: 'editCardProperty',
ShareBoard: 'shareBoard',
ViewBoard: 'viewBoard',
CreateBoard: 'createBoard',
DuplicateBoard: 'duplicateBoard',
DeleteBoard: 'deleteBoard',
ShareBoard: 'shareBoard',
CreateBoardTemplate: 'createBoardTemplate',
CreateBoardViaTemplate: 'createBoardViaTemplate',
AddTemplateFromBoard: 'AddTemplateFromBoard',
CreateBoardView: 'createBoardView',
DuplicateBoardView: 'duplicagteBoardView',
DeleteBoardView: 'deleteBoardView',
EditCardProperty: 'editCardProperty',
ViewCard: 'viewCard',
CreateCard: 'createCard',
CreateCardTemplate: 'createCardTemplate',
CreateCardViaTemplate: 'createCardViaTemplate',
DuplicateCard: 'duplicateCard',
DeleteCard: 'deleteCard',
AddTemplateFromCard: 'addTemplateFromCard',
ViewSharedBoard: 'viewSharedBoard',
}
interface IEventProps {
workspaceID?: string,
board?: string,
view?: string,
viewType?: string,
card?: string,
cardTemplateId?: string,
boardTemplateId?: string,
shareBoardEnabled?: boolean,
}
class TelemetryClient {
public telemetryHandler?: TelemetryHandler
public user?: IUser
@ -30,7 +53,7 @@ class TelemetryClient {
this.user = user
}
trackEvent(category: string, event: string, props?: unknown): void {
trackEvent(category: string, event: string, props?: IEventProps): void {
if (this.telemetryHandler) {
const userId = this.user?.id
this.telemetryHandler.trackEvent(userId || '', '', category, event, props)