feat(fe2): mp actions (federations, comments, lights, & more)
This commit is contained in:
@@ -155,7 +155,12 @@ const search = ref('')
|
||||
|
||||
const mp = useMixpanel()
|
||||
const trackFederateAll = () =>
|
||||
mp.track('Viewer Action', { type: 'action', name: 'view-all-models' })
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'federation',
|
||||
action: 'view-all',
|
||||
source: 'project page'
|
||||
})
|
||||
|
||||
const canContribute = computed(() => canModifyModels(props.project))
|
||||
const showNewDialog = ref(false)
|
||||
|
||||
@@ -105,7 +105,12 @@ const props = defineProps<{
|
||||
|
||||
const mp = useMixpanel()
|
||||
const trackFederateAll = () =>
|
||||
mp.track('Viewer Action', { type: 'action', name: 'view-all-models' })
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'federation',
|
||||
action: 'view-all',
|
||||
source: 'all models page'
|
||||
})
|
||||
|
||||
const queryLoading = ref(false)
|
||||
const search = ref('')
|
||||
|
||||
@@ -284,7 +284,12 @@ const importArea = ref(
|
||||
|
||||
const mp = useMixpanel()
|
||||
const trackFederateModels = () =>
|
||||
mp.track('Viewer Action', { type: 'action', name: 'view-all-submodels' })
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'federation',
|
||||
action: 'view-all',
|
||||
source: 'model grid item'
|
||||
})
|
||||
|
||||
const expanded = ref(false)
|
||||
const showActionsMenu = ref(false)
|
||||
|
||||
@@ -98,6 +98,7 @@ import { Nullable } from '@speckle/shared'
|
||||
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
|
||||
import { LimitedUser } from '~~/lib/common/generated/gql/graphql'
|
||||
import { SetFullyRequired } from '~~/lib/common/helpers/type'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { useViewerUserActivityTracking } from '~~/lib/viewer/composables/activity'
|
||||
import {
|
||||
CommentBubbleModel,
|
||||
@@ -200,10 +201,25 @@ const spotlightUser = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
const mp = useMixpanel()
|
||||
function setUserSpotlight(sessionId: string) {
|
||||
if (spotlightUserSessionId.value === sessionId)
|
||||
return (spotlightUserSessionId.value = null)
|
||||
if (spotlightUserSessionId.value === sessionId) {
|
||||
spotlightUserSessionId.value = null
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'spotlight-mode',
|
||||
action: 'stop',
|
||||
source: 'navbar'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
spotlightUserSessionId.value = sessionId
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'spotlight-mode',
|
||||
action: 'start',
|
||||
source: 'navbar'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -323,7 +323,12 @@ const changeExpanded = (newVal: boolean) => {
|
||||
isExpanded: newVal
|
||||
})
|
||||
emit('update:expanded', newVal)
|
||||
mp.track('Comment Action', { type: 'action', name: 'toggle', status: newVal })
|
||||
mp.track('Comment Action', {
|
||||
type: 'action',
|
||||
name: 'toggle',
|
||||
status: newVal,
|
||||
source: 'bubble'
|
||||
})
|
||||
}
|
||||
|
||||
const canArchiveOrUnarchive = computed(
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { UserActivityModel } from '~~/lib/viewer/composables/activity'
|
||||
import { useAnimatingEllipsis } from '~~/lib/viewer/composables/commentBubbles'
|
||||
import { useInjectedViewerInterfaceState } from '~~/lib/viewer/composables/setup'
|
||||
@@ -45,10 +46,25 @@ const isCreatingNewThread = computed(
|
||||
!props.user.state.ui.threads.openThread.threadId
|
||||
)
|
||||
|
||||
const mp = useMixpanel()
|
||||
function setUserSpotlight() {
|
||||
if (spotlightUserSessionId.value === props.user.sessionId)
|
||||
return (spotlightUserSessionId.value = null)
|
||||
if (spotlightUserSessionId.value === props.user.sessionId) {
|
||||
spotlightUserSessionId.value = null
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'spotlight-mode',
|
||||
action: 'stop',
|
||||
source: 'cursor'
|
||||
})
|
||||
return
|
||||
}
|
||||
spotlightUserSessionId.value = props.user.sessionId || null
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'spotlight-mode',
|
||||
action: 'start',
|
||||
source: 'cursor'
|
||||
})
|
||||
}
|
||||
|
||||
watch(isCreatingNewThread, (isCreating) => {
|
||||
|
||||
@@ -67,6 +67,7 @@ import { useActiveUser } from '~~/lib/auth/composables/activeUser'
|
||||
import { useArchiveComment } from '~~/lib/viewer/composables/commentManagement'
|
||||
import { ToastNotificationType, useGlobalToast } from '~~/lib/common/composables/toast'
|
||||
import { Roles } from '@speckle/shared'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
|
||||
const props = defineProps<{
|
||||
thread: LoadedCommentThread
|
||||
@@ -74,9 +75,20 @@ const props = defineProps<{
|
||||
|
||||
const { resourceItems } = useInjectedViewerLoadedResources()
|
||||
const {
|
||||
threads: { open, openThread }
|
||||
threads: { open: openThreadRaw, openThread }
|
||||
} = useInjectedViewerInterfaceState()
|
||||
|
||||
const mp = useMixpanel()
|
||||
const open = (id: string) => {
|
||||
openThreadRaw(id)
|
||||
mp.track('Comment Action', {
|
||||
type: 'action',
|
||||
name: 'toggle',
|
||||
status: !isOpenInViewer.value,
|
||||
source: 'sidebar'
|
||||
})
|
||||
}
|
||||
|
||||
const formattedDate = computed(() => dayjs(props.thread.createdAt).from(dayjs()))
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@@ -127,6 +139,11 @@ const canArchiveOrUnarchive = computed(
|
||||
|
||||
const toggleCommentResolvedStatus = async () => {
|
||||
await archiveComment(props.thread.id, !props.thread.archived)
|
||||
mp.track('Comment Action', {
|
||||
type: 'action',
|
||||
name: 'archive',
|
||||
status: !props.thread.archived
|
||||
})
|
||||
triggerNotification({
|
||||
description: `Thread ${props.thread.archived ? 'reopened.' : 'resolved.'}`,
|
||||
type: ToastNotificationType.Info
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
:version-id="versionId"
|
||||
:last="index === modelsAndVersionIds.length - 1"
|
||||
:show-remove="showRemove"
|
||||
@remove="(id) => removeModel(id)"
|
||||
@remove="(id:string) => removeModel(id)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
} from '~~/lib/viewer/composables/setup'
|
||||
import { PlusIcon, CheckIcon, MinusIcon } from '@heroicons/vue/24/solid'
|
||||
import { SpeckleViewer } from '@speckle/shared'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
|
||||
defineEmits(['close'])
|
||||
|
||||
@@ -56,6 +57,7 @@ const { items } = useInjectedViewerRequestedResources()
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
const mp = useMixpanel()
|
||||
const removeModel = async (modelId: string) => {
|
||||
// Convert requested resource string to references to specific models
|
||||
// to ensure remove works even when we have "all" or "$folder" in the URL
|
||||
@@ -69,7 +71,7 @@ const removeModel = async (modelId: string) => {
|
||||
builder.addObject(loadedResource.objectId)
|
||||
}
|
||||
}
|
||||
|
||||
mp.track('Viewer Action', { type: 'action', name: 'federation', action: 'remove' })
|
||||
await items.update(builder.toResources())
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { SpeckleViewer } from '@speckle/shared'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { LayoutTabItem } from '~~/lib/layout/helpers/components'
|
||||
import { useInjectedViewerRequestedResources } from '~~/lib/viewer/composables/setup'
|
||||
|
||||
@@ -37,12 +38,22 @@ const open = computed({
|
||||
set: (newVal) => emit('update:open', newVal)
|
||||
})
|
||||
|
||||
const mp = useMixpanel()
|
||||
|
||||
const onModelChosen = async (params: { modelId: string }) => {
|
||||
const { modelId } = params
|
||||
await items.update([
|
||||
...items.value,
|
||||
...SpeckleViewer.ViewerRoute.resourceBuilder().addModel(modelId).toResources()
|
||||
])
|
||||
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'federation',
|
||||
action: 'add',
|
||||
resource: 'model'
|
||||
})
|
||||
|
||||
open.value = false
|
||||
}
|
||||
|
||||
@@ -55,6 +66,14 @@ const onObjectsChosen = async (params: { objectIds: string[] }) => {
|
||||
}
|
||||
|
||||
await items.update([...items.value, ...resourcesApi.toResources()])
|
||||
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'federation',
|
||||
action: 'add',
|
||||
resource: 'object'
|
||||
})
|
||||
|
||||
open.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -80,7 +80,6 @@ const onSubmit = handleSubmit((payload) => {
|
||||
const { objectIdsOrUrl } = payload
|
||||
const ids = removeRedundantIds(extractObjectIds(objectIdsOrUrl) || [])
|
||||
if (!ids?.length) return
|
||||
|
||||
emit('chosen', { objectIds: ids })
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -77,15 +77,27 @@ import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
|
||||
import { SunLightConfiguration } from '@speckle/viewer'
|
||||
import { SunIcon } from '@heroicons/vue/24/outline'
|
||||
import { useInjectedViewerState } from '~~/lib/viewer/composables/setup'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { debounce } from 'lodash-es'
|
||||
|
||||
const mp = useMixpanel()
|
||||
const debounceTrackLightConfigChange = debounce(() => {
|
||||
mp.track('Viewer Action', {
|
||||
type: 'action',
|
||||
name: 'light-config-change'
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
const createLightConfigComputed = <K extends keyof SunLightConfiguration>(key: K) =>
|
||||
computed({
|
||||
get: () => lightConfig.value[key],
|
||||
set: (newVal) =>
|
||||
(lightConfig.value = {
|
||||
set: (newVal) => {
|
||||
lightConfig.value = {
|
||||
...lightConfig.value,
|
||||
[key]: newVal
|
||||
})
|
||||
}
|
||||
debounceTrackLightConfigChange()
|
||||
}
|
||||
})
|
||||
|
||||
const {
|
||||
|
||||
@@ -2,12 +2,11 @@ import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
if (process.server) return
|
||||
const mixpanel = useMixpanel()
|
||||
const mp = useMixpanel()
|
||||
const pathDefinition = to.matched[to.matched.length - 1].path
|
||||
const path = to.path
|
||||
mixpanel.track('Route Visited', {
|
||||
mp.track('Route Visited', {
|
||||
path,
|
||||
pathDefinition
|
||||
})
|
||||
console.log(path, pathDefinition)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user