Track action usage

This commit is contained in:
Tom Moor
2023-02-10 18:56:12 -05:00
parent bb6f4b1c1e
commit fcbd4d3d28
10 changed files with 106 additions and 4 deletions

View File

@@ -23,6 +23,7 @@ const ColorCollectionIcon = ({ collection }: { collection: Collection }) => {
export const openCollection = createAction({ export const openCollection = createAction({
name: ({ t }) => t("Open collection"), name: ({ t }) => t("Open collection"),
analyticsName: "Open collection",
section: CollectionSection, section: CollectionSection,
shortcut: ["o", "c"], shortcut: ["o", "c"],
icon: <CollectionIcon />, icon: <CollectionIcon />,
@@ -42,6 +43,7 @@ export const openCollection = createAction({
export const createCollection = createAction({ export const createCollection = createAction({
name: ({ t }) => t("New collection"), name: ({ t }) => t("New collection"),
analyticsName: "New collection",
section: CollectionSection, section: CollectionSection,
icon: <PlusIcon />, icon: <PlusIcon />,
keywords: "create", keywords: "create",
@@ -60,6 +62,7 @@ export const createCollection = createAction({
export const editCollection = createAction({ export const editCollection = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? `${t("Edit")}` : t("Edit collection"), isContextMenu ? `${t("Edit")}` : t("Edit collection"),
analyticsName: "Edit collection",
section: CollectionSection, section: CollectionSection,
icon: <EditIcon />, icon: <EditIcon />,
visible: ({ stores, activeCollectionId }) => visible: ({ stores, activeCollectionId }) =>
@@ -85,6 +88,7 @@ export const editCollection = createAction({
export const editCollectionPermissions = createAction({ export const editCollectionPermissions = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? `${t("Permissions")}` : t("Collection permissions"), isContextMenu ? `${t("Permissions")}` : t("Collection permissions"),
analyticsName: "Collection permissions",
section: CollectionSection, section: CollectionSection,
icon: <PadlockIcon />, icon: <PadlockIcon />,
visible: ({ stores, activeCollectionId }) => visible: ({ stores, activeCollectionId }) =>
@@ -104,6 +108,7 @@ export const editCollectionPermissions = createAction({
export const starCollection = createAction({ export const starCollection = createAction({
name: ({ t }) => t("Star"), name: ({ t }) => t("Star"),
analyticsName: "Star collection",
section: CollectionSection, section: CollectionSection,
icon: <StarredIcon />, icon: <StarredIcon />,
keywords: "favorite bookmark", keywords: "favorite bookmark",
@@ -129,6 +134,7 @@ export const starCollection = createAction({
export const unstarCollection = createAction({ export const unstarCollection = createAction({
name: ({ t }) => t("Unstar"), name: ({ t }) => t("Unstar"),
analyticsName: "Unstar collection",
section: CollectionSection, section: CollectionSection,
icon: <UnstarredIcon />, icon: <UnstarredIcon />,
keywords: "unfavorite unbookmark", keywords: "unfavorite unbookmark",

View File

@@ -45,6 +45,7 @@ import {
export const openDocument = createAction({ export const openDocument = createAction({
name: ({ t }) => t("Open document"), name: ({ t }) => t("Open document"),
analyticsName: "Open document",
section: DocumentSection, section: DocumentSection,
shortcut: ["o", "d"], shortcut: ["o", "d"],
keywords: "go to", keywords: "go to",
@@ -69,6 +70,7 @@ export const openDocument = createAction({
export const createDocument = createAction({ export const createDocument = createAction({
name: ({ t }) => t("New document"), name: ({ t }) => t("New document"),
analyticsName: "New document",
section: DocumentSection, section: DocumentSection,
icon: <NewDocumentIcon />, icon: <NewDocumentIcon />,
keywords: "create", keywords: "create",
@@ -82,6 +84,7 @@ export const createDocument = createAction({
export const starDocument = createAction({ export const starDocument = createAction({
name: ({ t }) => t("Star"), name: ({ t }) => t("Star"),
analyticsName: "Star document",
section: DocumentSection, section: DocumentSection,
icon: <StarredIcon />, icon: <StarredIcon />,
keywords: "favorite bookmark", keywords: "favorite bookmark",
@@ -106,6 +109,7 @@ export const starDocument = createAction({
export const unstarDocument = createAction({ export const unstarDocument = createAction({
name: ({ t }) => t("Unstar"), name: ({ t }) => t("Unstar"),
analyticsName: "Unstar document",
section: DocumentSection, section: DocumentSection,
icon: <UnstarredIcon />, icon: <UnstarredIcon />,
keywords: "unfavorite unbookmark", keywords: "unfavorite unbookmark",
@@ -131,6 +135,7 @@ export const unstarDocument = createAction({
export const publishDocument = createAction({ export const publishDocument = createAction({
name: ({ t }) => t("Publish"), name: ({ t }) => t("Publish"),
analyticsName: "Publish document",
section: DocumentSection, section: DocumentSection,
icon: <PublishIcon />, icon: <PublishIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -171,6 +176,7 @@ export const publishDocument = createAction({
export const unpublishDocument = createAction({ export const unpublishDocument = createAction({
name: ({ t }) => t("Unpublish"), name: ({ t }) => t("Unpublish"),
analyticsName: "Unpublish document",
section: DocumentSection, section: DocumentSection,
icon: <UnpublishIcon />, icon: <UnpublishIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -196,6 +202,7 @@ export const unpublishDocument = createAction({
export const subscribeDocument = createAction({ export const subscribeDocument = createAction({
name: ({ t }) => t("Subscribe"), name: ({ t }) => t("Subscribe"),
analyticsName: "Subscribe to document",
section: DocumentSection, section: DocumentSection,
icon: <SubscribeIcon />, icon: <SubscribeIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -227,6 +234,7 @@ export const subscribeDocument = createAction({
export const unsubscribeDocument = createAction({ export const unsubscribeDocument = createAction({
name: ({ t }) => t("Unsubscribe"), name: ({ t }) => t("Unsubscribe"),
analyticsName: "Unsubscribe from document",
section: DocumentSection, section: DocumentSection,
icon: <UnsubscribeIcon />, icon: <UnsubscribeIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -258,6 +266,7 @@ export const unsubscribeDocument = createAction({
export const downloadDocumentAsHTML = createAction({ export const downloadDocumentAsHTML = createAction({
name: ({ t }) => t("HTML"), name: ({ t }) => t("HTML"),
analyticsName: "Download document as HTML",
section: DocumentSection, section: DocumentSection,
keywords: "html export", keywords: "html export",
icon: <DownloadIcon />, icon: <DownloadIcon />,
@@ -276,6 +285,7 @@ export const downloadDocumentAsHTML = createAction({
export const downloadDocumentAsPDF = createAction({ export const downloadDocumentAsPDF = createAction({
name: ({ t }) => t("PDF"), name: ({ t }) => t("PDF"),
analyticsName: "Download document as PDF",
section: DocumentSection, section: DocumentSection,
keywords: "export", keywords: "export",
icon: <DownloadIcon />, icon: <DownloadIcon />,
@@ -303,6 +313,7 @@ export const downloadDocumentAsPDF = createAction({
export const downloadDocumentAsMarkdown = createAction({ export const downloadDocumentAsMarkdown = createAction({
name: ({ t }) => t("Markdown"), name: ({ t }) => t("Markdown"),
analyticsName: "Download document as Markdown",
section: DocumentSection, section: DocumentSection,
keywords: "md markdown export", keywords: "md markdown export",
icon: <DownloadIcon />, icon: <DownloadIcon />,
@@ -322,6 +333,7 @@ export const downloadDocumentAsMarkdown = createAction({
export const downloadDocument = createAction({ export const downloadDocument = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? t("Download") : t("Download document"), isContextMenu ? t("Download") : t("Download document"),
analyticsName: "Download document",
section: DocumentSection, section: DocumentSection,
icon: <DownloadIcon />, icon: <DownloadIcon />,
keywords: "export", keywords: "export",
@@ -335,6 +347,7 @@ export const downloadDocument = createAction({
export const duplicateDocument = createAction({ export const duplicateDocument = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? t("Duplicate") : t("Duplicate document"), isContextMenu ? t("Duplicate") : t("Duplicate document"),
analyticsName: "Duplicate document",
section: DocumentSection, section: DocumentSection,
icon: <DuplicateIcon />, icon: <DuplicateIcon />,
keywords: "copy", keywords: "copy",
@@ -371,7 +384,7 @@ export const pinDocumentToCollection = createAction({
collectionName, collectionName,
}); });
}, },
analyticsName: "Pin document to collection",
section: DocumentSection, section: DocumentSection,
icon: <PinIcon />, icon: <PinIcon />,
iconInContextMenu: false, iconInContextMenu: false,
@@ -407,6 +420,7 @@ export const pinDocumentToCollection = createAction({
*/ */
export const pinDocumentToHome = createAction({ export const pinDocumentToHome = createAction({
name: ({ t }) => t("Pin to home"), name: ({ t }) => t("Pin to home"),
analyticsName: "Pin document to home",
section: DocumentSection, section: DocumentSection,
icon: <PinIcon />, icon: <PinIcon />,
iconInContextMenu: false, iconInContextMenu: false,
@@ -438,6 +452,7 @@ export const pinDocumentToHome = createAction({
export const pinDocument = createAction({ export const pinDocument = createAction({
name: ({ t }) => t("Pin"), name: ({ t }) => t("Pin"),
analyticsName: "Pin document",
section: DocumentSection, section: DocumentSection,
icon: <PinIcon />, icon: <PinIcon />,
children: [pinDocumentToCollection, pinDocumentToHome], children: [pinDocumentToCollection, pinDocumentToHome],
@@ -446,6 +461,7 @@ export const pinDocument = createAction({
export const printDocument = createAction({ export const printDocument = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? t("Print") : t("Print document"), isContextMenu ? t("Print") : t("Print document"),
analyticsName: "Print document",
section: DocumentSection, section: DocumentSection,
icon: <PrintIcon />, icon: <PrintIcon />,
visible: ({ activeDocumentId }) => !!(activeDocumentId && window.print), visible: ({ activeDocumentId }) => !!(activeDocumentId && window.print),
@@ -456,6 +472,7 @@ export const printDocument = createAction({
export const importDocument = createAction({ export const importDocument = createAction({
name: ({ t }) => t("Import document"), name: ({ t }) => t("Import document"),
analyticsName: "Import document",
section: DocumentSection, section: DocumentSection,
icon: <ImportIcon />, icon: <ImportIcon />,
keywords: "upload", keywords: "upload",
@@ -504,6 +521,7 @@ export const importDocument = createAction({
export const createTemplate = createAction({ export const createTemplate = createAction({
name: ({ t }) => t("Templatize"), name: ({ t }) => t("Templatize"),
analyticsName: "Templatize document",
section: DocumentSection, section: DocumentSection,
icon: <ShapesIcon />, icon: <ShapesIcon />,
keywords: "new create template", keywords: "new create template",
@@ -536,8 +554,9 @@ export const createTemplate = createAction({
export const openRandomDocument = createAction({ export const openRandomDocument = createAction({
id: "random", id: "random",
section: DocumentSection,
name: ({ t }) => t(`Open random document`), name: ({ t }) => t(`Open random document`),
analyticsName: "Open random document",
section: DocumentSection,
icon: <ShuffleIcon />, icon: <ShuffleIcon />,
perform: ({ stores, activeDocumentId }) => { perform: ({ stores, activeDocumentId }) => {
const documentPaths = stores.collections.pathsToDocuments.filter( const documentPaths = stores.collections.pathsToDocuments.filter(
@@ -555,9 +574,10 @@ export const openRandomDocument = createAction({
export const searchDocumentsForQuery = (searchQuery: string) => export const searchDocumentsForQuery = (searchQuery: string) =>
createAction({ createAction({
id: "search", id: "search",
section: DocumentSection,
name: ({ t }) => name: ({ t }) =>
t(`Search documents for "{{searchQuery}}"`, { searchQuery }), t(`Search documents for "{{searchQuery}}"`, { searchQuery }),
analyticsName: "Search documents",
section: DocumentSection,
icon: <SearchIcon />, icon: <SearchIcon />,
perform: () => history.push(searchPath(searchQuery)), perform: () => history.push(searchPath(searchQuery)),
visible: ({ location }) => location.pathname !== searchPath(), visible: ({ location }) => location.pathname !== searchPath(),
@@ -565,6 +585,7 @@ export const searchDocumentsForQuery = (searchQuery: string) =>
export const moveDocument = createAction({ export const moveDocument = createAction({
name: ({ t }) => t("Move"), name: ({ t }) => t("Move"),
analyticsName: "Move document",
section: DocumentSection, section: DocumentSection,
icon: <MoveIcon />, icon: <MoveIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -593,6 +614,7 @@ export const moveDocument = createAction({
export const archiveDocument = createAction({ export const archiveDocument = createAction({
name: ({ t }) => t("Archive"), name: ({ t }) => t("Archive"),
analyticsName: "Archive document",
section: DocumentSection, section: DocumentSection,
icon: <ArchiveIcon />, icon: <ArchiveIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -618,6 +640,7 @@ export const archiveDocument = createAction({
export const deleteDocument = createAction({ export const deleteDocument = createAction({
name: ({ t }) => t("Delete"), name: ({ t }) => t("Delete"),
analyticsName: "Delete document",
section: DocumentSection, section: DocumentSection,
icon: <TrashIcon />, icon: <TrashIcon />,
dangerous: true, dangerous: true,
@@ -652,6 +675,7 @@ export const deleteDocument = createAction({
export const permanentlyDeleteDocument = createAction({ export const permanentlyDeleteDocument = createAction({
name: ({ t }) => t("Permanently delete"), name: ({ t }) => t("Permanently delete"),
analyticsName: "Permanently delete document",
section: DocumentSection, section: DocumentSection,
icon: <CrossIcon />, icon: <CrossIcon />,
dangerous: true, dangerous: true,
@@ -686,6 +710,7 @@ export const permanentlyDeleteDocument = createAction({
export const openDocumentHistory = createAction({ export const openDocumentHistory = createAction({
name: ({ t }) => t("History"), name: ({ t }) => t("History"),
analyticsName: "Open document history",
section: DocumentSection, section: DocumentSection,
icon: <HistoryIcon />, icon: <HistoryIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {
@@ -706,6 +731,7 @@ export const openDocumentHistory = createAction({
export const openDocumentInsights = createAction({ export const openDocumentInsights = createAction({
name: ({ t }) => t("Insights"), name: ({ t }) => t("Insights"),
analyticsName: "Open document insights",
section: DocumentSection, section: DocumentSection,
icon: <LightBulbIcon />, icon: <LightBulbIcon />,
visible: ({ activeDocumentId, stores }) => { visible: ({ activeDocumentId, stores }) => {

View File

@@ -43,6 +43,7 @@ import {
export const navigateToHome = createAction({ export const navigateToHome = createAction({
name: ({ t }) => t("Home"), name: ({ t }) => t("Home"),
analyticsName: "Navigate to home",
section: NavigationSection, section: NavigationSection,
shortcut: ["d"], shortcut: ["d"],
icon: <HomeIcon />, icon: <HomeIcon />,
@@ -54,12 +55,14 @@ export const navigateToRecentSearchQuery = (searchQuery: SearchQuery) =>
createAction({ createAction({
section: RecentSearchesSection, section: RecentSearchesSection,
name: searchQuery.query, name: searchQuery.query,
analyticsName: "Navigate to recent search query",
icon: <SearchIcon />, icon: <SearchIcon />,
perform: () => history.push(searchPath(searchQuery.query)), perform: () => history.push(searchPath(searchQuery.query)),
}); });
export const navigateToDrafts = createAction({ export const navigateToDrafts = createAction({
name: ({ t }) => t("Drafts"), name: ({ t }) => t("Drafts"),
analyticsName: "Navigate to drafts",
section: NavigationSection, section: NavigationSection,
icon: <EditIcon />, icon: <EditIcon />,
perform: () => history.push(draftsPath()), perform: () => history.push(draftsPath()),
@@ -68,6 +71,7 @@ export const navigateToDrafts = createAction({
export const navigateToTemplates = createAction({ export const navigateToTemplates = createAction({
name: ({ t }) => t("Templates"), name: ({ t }) => t("Templates"),
analyticsName: "Navigate to templates",
section: NavigationSection, section: NavigationSection,
icon: <ShapesIcon />, icon: <ShapesIcon />,
perform: () => history.push(templatesPath()), perform: () => history.push(templatesPath()),
@@ -76,6 +80,7 @@ export const navigateToTemplates = createAction({
export const navigateToArchive = createAction({ export const navigateToArchive = createAction({
name: ({ t }) => t("Archive"), name: ({ t }) => t("Archive"),
analyticsName: "Navigate to archive",
section: NavigationSection, section: NavigationSection,
shortcut: ["g", "a"], shortcut: ["g", "a"],
icon: <ArchiveIcon />, icon: <ArchiveIcon />,
@@ -85,6 +90,7 @@ export const navigateToArchive = createAction({
export const navigateToTrash = createAction({ export const navigateToTrash = createAction({
name: ({ t }) => t("Trash"), name: ({ t }) => t("Trash"),
analyticsName: "Navigate to trash",
section: NavigationSection, section: NavigationSection,
icon: <TrashIcon />, icon: <TrashIcon />,
perform: () => history.push(trashPath()), perform: () => history.push(trashPath()),
@@ -93,6 +99,7 @@ export const navigateToTrash = createAction({
export const navigateToSettings = createAction({ export const navigateToSettings = createAction({
name: ({ t }) => t("Settings"), name: ({ t }) => t("Settings"),
analyticsName: "Navigate to settings",
section: NavigationSection, section: NavigationSection,
shortcut: ["g", "s"], shortcut: ["g", "s"],
icon: <SettingsIcon />, icon: <SettingsIcon />,
@@ -103,6 +110,7 @@ export const navigateToSettings = createAction({
export const navigateToProfileSettings = createAction({ export const navigateToProfileSettings = createAction({
name: ({ t }) => t("Profile"), name: ({ t }) => t("Profile"),
analyticsName: "Navigate to profile settings",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <ProfileIcon />, icon: <ProfileIcon />,
@@ -111,6 +119,7 @@ export const navigateToProfileSettings = createAction({
export const navigateToAccountPreferences = createAction({ export const navigateToAccountPreferences = createAction({
name: ({ t }) => t("Preferences"), name: ({ t }) => t("Preferences"),
analyticsName: "Navigate to account preferences",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <SettingsIcon />, icon: <SettingsIcon />,
@@ -119,6 +128,7 @@ export const navigateToAccountPreferences = createAction({
export const openAPIDocumentation = createAction({ export const openAPIDocumentation = createAction({
name: ({ t }) => t("API documentation"), name: ({ t }) => t("API documentation"),
analyticsName: "Open API documentation",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <OpenIcon />, icon: <OpenIcon />,
@@ -127,6 +137,7 @@ export const openAPIDocumentation = createAction({
export const openFeedbackUrl = createAction({ export const openFeedbackUrl = createAction({
name: ({ t }) => t("Send us feedback"), name: ({ t }) => t("Send us feedback"),
analyticsName: "Open feedback",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <EmailIcon />, icon: <EmailIcon />,
@@ -135,12 +146,14 @@ export const openFeedbackUrl = createAction({
export const openBugReportUrl = createAction({ export const openBugReportUrl = createAction({
name: ({ t }) => t("Report a bug"), name: ({ t }) => t("Report a bug"),
analyticsName: "Open bug report",
section: NavigationSection, section: NavigationSection,
perform: () => window.open(githubIssuesUrl()), perform: () => window.open(githubIssuesUrl()),
}); });
export const openChangelog = createAction({ export const openChangelog = createAction({
name: ({ t }) => t("Changelog"), name: ({ t }) => t("Changelog"),
analyticsName: "Open changelog",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <OpenIcon />, icon: <OpenIcon />,
@@ -149,6 +162,7 @@ export const openChangelog = createAction({
export const openKeyboardShortcuts = createAction({ export const openKeyboardShortcuts = createAction({
name: ({ t }) => t("Keyboard shortcuts"), name: ({ t }) => t("Keyboard shortcuts"),
analyticsName: "Open keyboard shortcuts",
section: NavigationSection, section: NavigationSection,
shortcut: ["?"], shortcut: ["?"],
iconInContextMenu: false, iconInContextMenu: false,
@@ -166,6 +180,7 @@ export const downloadApp = createAction({
t("Download {{ platform }} app", { t("Download {{ platform }} app", {
platform: isMac() ? "macOS" : "Windows", platform: isMac() ? "macOS" : "Windows",
}), }),
analyticsName: "Download app",
section: NavigationSection, section: NavigationSection,
iconInContextMenu: false, iconInContextMenu: false,
icon: <BrowserIcon />, icon: <BrowserIcon />,
@@ -177,6 +192,7 @@ export const downloadApp = createAction({
export const logout = createAction({ export const logout = createAction({
name: ({ t }) => t("Log out"), name: ({ t }) => t("Log out"),
analyticsName: "Log out",
section: NavigationSection, section: NavigationSection,
icon: <LogoutIcon />, icon: <LogoutIcon />,
perform: () => stores.auth.logout(), perform: () => stores.auth.logout(),

View File

@@ -10,6 +10,7 @@ import { documentHistoryUrl, matchDocumentHistory } from "~/utils/routeHelpers";
export const restoreRevision = createAction({ export const restoreRevision = createAction({
name: ({ t }) => t("Restore revision"), name: ({ t }) => t("Restore revision"),
analyticsName: "Restore revision",
icon: <RestoreIcon />, icon: <RestoreIcon />,
section: RevisionSection, section: RevisionSection,
visible: ({ activeDocumentId, stores }) => visible: ({ activeDocumentId, stores }) =>
@@ -50,6 +51,7 @@ export const restoreRevision = createAction({
export const copyLinkToRevision = createAction({ export const copyLinkToRevision = createAction({
name: ({ t }) => t("Copy link"), name: ({ t }) => t("Copy link"),
analyticsName: "Copy link to revision",
icon: <LinkIcon />, icon: <LinkIcon />,
section: RevisionSection, section: RevisionSection,
perform: async ({ activeDocumentId, stores, t }) => { perform: async ({ activeDocumentId, stores, t }) => {

View File

@@ -7,6 +7,7 @@ import { SettingsSection } from "~/actions/sections";
export const changeToDarkTheme = createAction({ export const changeToDarkTheme = createAction({
name: ({ t }) => t("Dark"), name: ({ t }) => t("Dark"),
analyticsName: "Change to dark theme",
icon: <MoonIcon />, icon: <MoonIcon />,
iconInContextMenu: false, iconInContextMenu: false,
keywords: "theme dark night", keywords: "theme dark night",
@@ -17,6 +18,7 @@ export const changeToDarkTheme = createAction({
export const changeToLightTheme = createAction({ export const changeToLightTheme = createAction({
name: ({ t }) => t("Light"), name: ({ t }) => t("Light"),
analyticsName: "Change to light theme",
icon: <SunIcon />, icon: <SunIcon />,
iconInContextMenu: false, iconInContextMenu: false,
keywords: "theme light day", keywords: "theme light day",
@@ -27,6 +29,7 @@ export const changeToLightTheme = createAction({
export const changeToSystemTheme = createAction({ export const changeToSystemTheme = createAction({
name: ({ t }) => t("System"), name: ({ t }) => t("System"),
analyticsName: "Change to system theme",
icon: <BrowserIcon />, icon: <BrowserIcon />,
iconInContextMenu: false, iconInContextMenu: false,
keywords: "theme system default", keywords: "theme system default",
@@ -38,6 +41,7 @@ export const changeToSystemTheme = createAction({
export const changeTheme = createAction({ export const changeTheme = createAction({
name: ({ t, isContextMenu }) => name: ({ t, isContextMenu }) =>
isContextMenu ? t("Appearance") : t("Change theme"), isContextMenu ? t("Appearance") : t("Change theme"),
analyticsName: "Change theme",
placeholder: ({ t }) => t("Change theme to"), placeholder: ({ t }) => t("Change theme to"),
icon: () => icon: () =>
stores.ui.resolvedTheme === "light" ? <SunIcon /> : <MoonIcon />, stores.ui.resolvedTheme === "light" ? <SunIcon /> : <MoonIcon />,

View File

@@ -14,6 +14,7 @@ export const createTeamsList = ({ stores }: { stores: RootStore }) => {
stores.auth.availableTeams?.map((session) => ({ stores.auth.availableTeams?.map((session) => ({
id: `switch-${session.id}`, id: `switch-${session.id}`,
name: session.name, name: session.name,
analyticsName: "Switch workspace",
section: TeamSection, section: TeamSection,
keywords: "change switch workspace organization team", keywords: "change switch workspace organization team",
icon: () => ( icon: () => (
@@ -38,6 +39,7 @@ export const createTeamsList = ({ stores }: { stores: RootStore }) => {
export const switchTeam = createAction({ export const switchTeam = createAction({
name: ({ t }) => t("Switch workspace"), name: ({ t }) => t("Switch workspace"),
placeholder: ({ t }) => t("Select a workspace"), placeholder: ({ t }) => t("Select a workspace"),
analyticsName: "Switch workspace",
keywords: "change switch workspace organization team", keywords: "change switch workspace organization team",
section: TeamSection, section: TeamSection,
visible: ({ stores }) => visible: ({ stores }) =>
@@ -47,6 +49,7 @@ export const switchTeam = createAction({
export const createTeam = createAction({ export const createTeam = createAction({
name: ({ t }) => `${t("New workspace")}`, name: ({ t }) => `${t("New workspace")}`,
analyticsName: "New workspace",
keywords: "create change switch workspace organization team", keywords: "create change switch workspace organization team",
section: TeamSection, section: TeamSection,
icon: <PlusIcon />, icon: <PlusIcon />,

View File

@@ -7,6 +7,7 @@ import { UserSection } from "~/actions/sections";
export const inviteUser = createAction({ export const inviteUser = createAction({
name: ({ t }) => `${t("Invite people")}`, name: ({ t }) => `${t("Invite people")}`,
analyticsName: "Invite people",
icon: <PlusIcon />, icon: <PlusIcon />,
keywords: "team member workspace user", keywords: "team member workspace user",
section: UserSection, section: UserSection,

View File

@@ -9,6 +9,7 @@ import {
MenuItemButton, MenuItemButton,
MenuItemWithChildren, MenuItemWithChildren,
} from "~/types"; } from "~/types";
import Analytics from "~/utils/Analytics";
function resolve<T>(value: any, context: ActionContext): T { function resolve<T>(value: any, context: ActionContext): T {
return typeof value === "function" ? value(context) : value; return typeof value === "function" ? value(context) : value;
@@ -17,6 +18,21 @@ function resolve<T>(value: any, context: ActionContext): T {
export function createAction(definition: Optional<Action, "id">): Action { export function createAction(definition: Optional<Action, "id">): Action {
return { return {
...definition, ...definition,
perform: (context) => {
// We muse use the specific analytics name here as the action name is
// translated and potentially contains user strings.
if (definition.analyticsName) {
Analytics.track("perform_action", definition.analyticsName, {
context: context.isButton
? "button"
: context.isCommandBar
? "commandbar"
: "contextmenu",
});
}
return definition.perform?.(context);
},
id: uuidv4(), id: uuidv4(),
}; };
} }
@@ -93,12 +109,13 @@ export function actionToKBar(
{ {
id: action.id, id: action.id,
name: resolvedName, name: resolvedName,
analyticsName: action.analyticsName,
section: resolvedSection, section: resolvedSection,
placeholder: resolvedPlaceholder, placeholder: resolvedPlaceholder,
keywords: action.keywords ?? "", keywords: action.keywords ?? "",
shortcut: action.shortcut || [], shortcut: action.shortcut || [],
icon: resolvedIcon, icon: resolvedIcon,
perform: action.perform ? () => action?.perform?.(context) : undefined, perform: () => action.perform?.(context),
}, },
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
].concat(children.map((child) => ({ ...child, parent: action.id }))); ].concat(children.map((child) => ({ ...child, parent: action.id })));

View File

@@ -89,6 +89,7 @@ export type ActionContext = {
export type Action = { export type Action = {
type?: undefined; type?: undefined;
id: string; id: string;
analyticsName?: string;
name: ((context: ActionContext) => string) | string; name: ((context: ActionContext) => string) | string;
section: ((context: ActionContext) => string) | string; section: ((context: ActionContext) => string) | string;
shortcut?: string[]; shortcut?: string[];

26
app/utils/Analytics.ts Normal file
View File

@@ -0,0 +1,26 @@
/**
* Helper class to track events across various analytics integrations
*/
export default class Analytics {
/**
* Send an event to Analytics
*
* @param event The event name
* @param action The action name
*/
public static track = (
event: string,
action: string,
metadata?: Record<string, string>
) => {
// GA3
ga?.("send", "event", event, action);
// GA4
window.dataLayer?.push({
event,
action,
...metadata,
});
};
}