From f84166efeab1761a0faf8a5cd6278e74b301c3e4 Mon Sep 17 00:00:00 2001 From: Bruce Tian Date: Mon, 27 Nov 2023 12:05:55 +1300 Subject: [PATCH 1/4] chore(metrics): add metrics to track search query in AL --- .../ActivityDetails/ActivityDetails.tsx | 13 ++++++- .../ActivityLibrary/ActivityLibrary.tsx | 34 +++++++++++++++++-- .../schemaExtensions/clientSchema.graphql | 1 + 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx b/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx index aafbb30bda8..230fc10af59 100644 --- a/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx +++ b/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx @@ -11,6 +11,8 @@ import {ActivityCard, ActivityCardImage} from '../ActivityCard' import ActivityDetailsSidebar from '../ActivityDetailsSidebar' import {CategoryID, CATEGORY_THEMES, QUICK_START_CATEGORY_ID} from '../Categories' import {TemplateDetails} from './TemplateDetails' +import SendClientSideEvent from '../../../utils/SendClientSideEvent' +import useAtmosphere from '../../../hooks/useAtmosphere' graphql` fragment ActivityDetails_template on MeetingTemplate { @@ -37,6 +39,7 @@ export const query = graphql` query ActivityDetailsQuery($activityId: ID!) { viewer { ...ActivityDetailsSidebar_viewer + activityLibrarySearch preferredTeamId tier activity(activityId: $activityId) { @@ -61,16 +64,24 @@ interface Props { } const ActivityDetails = (props: Props) => { + const atmosphere = useAtmosphere() const {queryRef} = props const data = usePreloadedQuery(query, queryRef) const {viewer} = data - const {activity, preferredTeamId, teams} = viewer + const {activity, activityLibrarySearch, preferredTeamId, teams} = viewer const history = useHistory<{prevCategory?: string}>() const [isEditing, setIsEditing] = useState(false) if (!activity) { return } + SendClientSideEvent(atmosphere, 'Viewed Template', { + meetingType: activity.type, + scope: activity.scope, + templateName: activity.name, + isFree: activity.isFree, + queryString: activityLibrarySearch + }) const {category, illustrationUrl, viewerLowestScope} = activity const prevCategory = history.location.state?.prevCategory const categoryLink = `/activity-library/category/${ diff --git a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx index fef35dfe33d..6230df32390 100644 --- a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx +++ b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx @@ -2,7 +2,7 @@ import * as ScrollArea from '@radix-ui/react-scroll-area' import graphql from 'babel-plugin-relay/macro' import clsx from 'clsx' import React, {useMemo} from 'react' -import {PreloadedQuery, usePreloadedQuery} from 'react-relay' +import {PreloadedQuery, commitLocalUpdate, usePreloadedQuery} from 'react-relay' import {Redirect} from 'react-router' import {Link} from 'react-router-dom' import {ActivityLibraryQuery} from '~/__generated__/ActivityLibraryQuery.graphql' @@ -25,6 +25,8 @@ import { } from './Categories' import CreateActivityCard from './CreateActivityCard' import SearchBar from './SearchBar' +import useAtmosphere from '../../hooks/useAtmosphere' +import SendClientSideEvent from '../../utils/SendClientSideEvent' graphql` fragment ActivityLibrary_templateSearchDocument on MeetingTemplate { @@ -189,12 +191,26 @@ const ActivityGrid = ({templates, selectedCategory}: ActivityGridProps) => { const MAX_PER_SUBCATEGORY = 6 export const ActivityLibrary = (props: Props) => { + const atmosphere = useAtmosphere() const {queryRef} = props const data = usePreloadedQuery(query, queryRef) const {viewer} = data const {featureFlags, availableTemplates, organizations} = viewer const hasOneOnOneFeatureFlag = !!organizations.find((org) => org.featureFlags.oneOnOne) + const setSearch = (value: string) => { + commitLocalUpdate(atmosphere, (store) => { + const viewer = store.getRoot().getLinkedRecord('viewer') + if (!viewer) return + viewer.setValue(value, 'activityLibrarySearch') + }) + if (value.length > 2) { + SendClientSideEvent(atmosphere, 'Activity Library Searched', { + queryString: value + }) + } + } + const templates = useMemo(() => { const templatesMap = availableTemplates.edges.map((edge) => edge.node) if (!hasOneOnOneFeatureFlag) { @@ -279,7 +295,13 @@ export const ActivityLibrary = (props: Props) => {
- + { + onQueryChange(e) + setSearch(e.target.value) + }} + />
{
- + { + onQueryChange(e) + setSearch(e.target.value) + }} + />
diff --git a/packages/client/schemaExtensions/clientSchema.graphql b/packages/client/schemaExtensions/clientSchema.graphql index e97c41c53d8..915fbf7685a 100644 --- a/packages/client/schemaExtensions/clientSchema.graphql +++ b/packages/client/schemaExtensions/clientSchema.graphql @@ -69,6 +69,7 @@ extend type User { # If positive, client clock is ahead of server clock by this many ms clientClockOffset: Int dashSearch: String + activityLibrarySearch: String pageName: String # The team we should default to in team pickers, etc. preferredTeamId: ID From d0c60244afe9808d416de013b9b4ab5bf786cd3f Mon Sep 17 00:00:00 2001 From: Bruce Tian Date: Mon, 27 Nov 2023 12:47:38 +1300 Subject: [PATCH 2/4] Only emit once --- .../ActivityDetails/ActivityDetails.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx b/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx index 230fc10af59..9f2b0114815 100644 --- a/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx +++ b/packages/client/components/ActivityLibrary/ActivityDetails/ActivityDetails.tsx @@ -1,6 +1,6 @@ import graphql from 'babel-plugin-relay/macro' import clsx from 'clsx' -import React, {useState} from 'react' +import React, {useEffect, useState} from 'react' import {PreloadedQuery, usePreloadedQuery} from 'react-relay' import {Redirect, useHistory} from 'react-router' import {Link} from 'react-router-dom' @@ -75,13 +75,16 @@ const ActivityDetails = (props: Props) => { if (!activity) { return } - SendClientSideEvent(atmosphere, 'Viewed Template', { - meetingType: activity.type, - scope: activity.scope, - templateName: activity.name, - isFree: activity.isFree, - queryString: activityLibrarySearch - }) + useEffect(() => { + SendClientSideEvent(atmosphere, 'Viewed Template', { + meetingType: activity.type, + scope: activity.scope, + templateName: activity.name, + isFree: activity.isFree, + queryString: activityLibrarySearch + }) + }, []) + const {category, illustrationUrl, viewerLowestScope} = activity const prevCategory = history.location.state?.prevCategory const categoryLink = `/activity-library/category/${ From 37afedd46453153fc431366b9e5a4ac5002d0dce Mon Sep 17 00:00:00 2001 From: Bruce Tian Date: Thu, 30 Nov 2023 10:58:44 +1300 Subject: [PATCH 3/4] Use debounce for searchQuery --- .../ActivityLibrary/ActivityLibrary.tsx | 17 +++++++++++------ packages/client/package.json | 3 ++- yarn.lock | 5 +++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx index 6230df32390..bf5856bdb06 100644 --- a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx +++ b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx @@ -1,7 +1,7 @@ import * as ScrollArea from '@radix-ui/react-scroll-area' import graphql from 'babel-plugin-relay/macro' import clsx from 'clsx' -import React, {useMemo} from 'react' +import React, {useEffect, useMemo} from 'react' import {PreloadedQuery, commitLocalUpdate, usePreloadedQuery} from 'react-relay' import {Redirect} from 'react-router' import {Link} from 'react-router-dom' @@ -27,6 +27,7 @@ import CreateActivityCard from './CreateActivityCard' import SearchBar from './SearchBar' import useAtmosphere from '../../hooks/useAtmosphere' import SendClientSideEvent from '../../utils/SendClientSideEvent' +import {useDebounce} from 'use-debounce' graphql` fragment ActivityLibrary_templateSearchDocument on MeetingTemplate { @@ -204,11 +205,6 @@ export const ActivityLibrary = (props: Props) => { if (!viewer) return viewer.setValue(value, 'activityLibrarySearch') }) - if (value.length > 2) { - SendClientSideEvent(atmosphere, 'Activity Library Searched', { - queryString: value - }) - } } const templates = useMemo(() => { @@ -227,6 +223,15 @@ export const ActivityLibrary = (props: Props) => { onQueryChange, resetQuery } = useSearchFilter(templates, getTemplateDocumentValue) + const [queryString] = useDebounce(searchQuery, 500) + + useEffect(() => { + if (queryString) { + SendClientSideEvent(atmosphere, 'Activity Library Searched', { + queryString + }) + } + }, [queryString]) const {match} = useRouter<{categoryId?: string}>() const { diff --git a/packages/client/package.json b/packages/client/package.json index 03bdf735627..996c001ec16 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -145,6 +145,7 @@ "tayden-clusterfck": "^0.7.0", "tlds": "^1.192.0", "tslib": "^2.4.0", - "unicode-substring": "^1.0.0" + "unicode-substring": "^1.0.0", + "use-debounce": "^10.0.0" } } diff --git a/yarn.lock b/yarn.lock index 0f5a51d2d7e..a8809b5d326 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23289,6 +23289,11 @@ use-composed-ref@^1.3.0: resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== +use-debounce@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-10.0.0.tgz#5091b18d6c16292605f588bae3c0d2cfae756ff2" + integrity sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A== + use-isomorphic-layout-effect@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" From ce6423bed08148b2c01b558e792775ec0a272985 Mon Sep 17 00:00:00 2001 From: Bruce Tian Date: Thu, 30 Nov 2023 13:44:49 +1300 Subject: [PATCH 4/4] Rename to debouncedSearchQuery --- .../client/components/ActivityLibrary/ActivityLibrary.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx index bf5856bdb06..c11bb1822a5 100644 --- a/packages/client/components/ActivityLibrary/ActivityLibrary.tsx +++ b/packages/client/components/ActivityLibrary/ActivityLibrary.tsx @@ -223,15 +223,15 @@ export const ActivityLibrary = (props: Props) => { onQueryChange, resetQuery } = useSearchFilter(templates, getTemplateDocumentValue) - const [queryString] = useDebounce(searchQuery, 500) + const [debouncedSearchQuery] = useDebounce(searchQuery, 500) useEffect(() => { - if (queryString) { + if (debouncedSearchQuery) { SendClientSideEvent(atmosphere, 'Activity Library Searched', { - queryString + debouncedSearchQuery }) } - }, [queryString]) + }, [debouncedSearchQuery]) const {match} = useRouter<{categoryId?: string}>() const {