refactor(fe2): Send user to dashboard after tour - skip checklist (#3404)
* Send user to dashboard after tour * Minor * Onboarding improvements * Style fixes * Add tooltip to finish button * hasAddedOverlay > disableNext * Remove step ref * Fix tooltip persisting
This commit is contained in:
committed by
GitHub
parent
693f751e38
commit
0191c8a8f5
@@ -22,7 +22,7 @@
|
||||
>
|
||||
<div
|
||||
v-show="item.expanded"
|
||||
class="transition bg-foundation rounded-lg shadow-md mb-8 mx-2 px-4 py-4 gap-2 sm:gap-4 sm:ml-12 sm:max-w-xs pointer-events-auto"
|
||||
class="transition bg-foundation-page border border-outline-3 rounded-lg shadow-md mb-8 mx-2 gap-2 sm:gap-4 sm:ml-12 sm:max-w-xs pointer-events-auto"
|
||||
>
|
||||
<div
|
||||
class="sm:hidden flex items-center justify-center w-full gap-3 mt-1 mb-3"
|
||||
@@ -41,21 +41,35 @@
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<slot></slot>
|
||||
<div class="px-6 py-4">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between pointer-events-auto mt-4">
|
||||
<div
|
||||
class="flex items-center justify-between pointer-events-auto px-6 py-2 border-t border-outline-3"
|
||||
>
|
||||
<slot name="actions">
|
||||
<FormButton text color="outline" @click="$emit('skip')">Skip</FormButton>
|
||||
<div class="flex justify-center space-x-2">
|
||||
<FormButton text size="sm" color="outline" @click="$emit('skip')">
|
||||
Skip
|
||||
</FormButton>
|
||||
<div class="flex justify-center items-center space-x-2">
|
||||
<FormButton
|
||||
v-show="index !== 0"
|
||||
:icon-left="ArrowLeftIcon"
|
||||
size="sm"
|
||||
color="outline"
|
||||
text
|
||||
@click="prev(index)"
|
||||
>
|
||||
<ArrowLeftIcon class="h-3 w-3 mr-1" />
|
||||
Previous
|
||||
</FormButton>
|
||||
<FormButton :icon-right="ArrowRightIcon" @click="next(index)">
|
||||
<div v-if="index === 2">
|
||||
<div v-if="!disableNext" v-tippy="'First add another model'">
|
||||
<FormButton disabled>Finish</FormButton>
|
||||
</div>
|
||||
<FormButton v-else @click="$emit('skip')">Finish</FormButton>
|
||||
</div>
|
||||
<FormButton v-else :icon-right="ArrowRightIcon" @click="next(index)">
|
||||
Next
|
||||
</FormButton>
|
||||
</div>
|
||||
@@ -83,6 +97,7 @@ defineEmits(['skip', 'previous', 'next'])
|
||||
const props = defineProps<{
|
||||
index: number
|
||||
item: SlideshowItem
|
||||
disableNext: boolean
|
||||
}>()
|
||||
|
||||
const {
|
||||
|
||||
@@ -2,48 +2,24 @@
|
||||
<div
|
||||
class="relative max-w-4xl w-screen h-[100dvh] flex items-center justify-center z-50"
|
||||
>
|
||||
<TourSegmentation v-if="showSegmentation && step === 0" @next="step++" />
|
||||
<TourSlideshow v-if="step === 1" @next="step++" />
|
||||
<!-- <OnboardingDialogManager v-if="step === 2" allow-escape @cancel="step++" /> -->
|
||||
<div
|
||||
v-if="step === 2 && !hasCompletedChecklistV1"
|
||||
class="relative w-full pointer-events-auto space-y-2 z-50"
|
||||
>
|
||||
<div
|
||||
v-if="!isSmallerOrEqualSm"
|
||||
class="pointer-events-none fixed inset-0 bg-neutral-100/70 dark:bg-neutral-900/70 transition-opacity z-50"
|
||||
/>
|
||||
<div v-if="!isSmallerOrEqualSm" class="relative z-50">
|
||||
<OnboardingChecklistV1 show-bottom-escape background @dismiss="step++" />
|
||||
</div>
|
||||
</div>
|
||||
<TourSegmentation v-if="showSegmentation" />
|
||||
<TourSlideshow v-else @next="$emit('complete')" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useViewerTour } from '~/lib/viewer/composables/tour'
|
||||
import { useSynchronizedCookie } from '~~/lib/common/composables/reactiveCookie'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
|
||||
const { isSmallerOrEqualSm } = useIsSmallerOrEqualThanBreakpoint()
|
||||
|
||||
const step = ref(0)
|
||||
const hasCompletedChecklistV1 = useSynchronizedCookie<boolean>(
|
||||
`hasCompletedChecklistV1`,
|
||||
{ default: () => false }
|
||||
)
|
||||
defineEmits(['complete'])
|
||||
|
||||
const { showSegmentation } = useViewerTour()
|
||||
|
||||
const mp = useMixpanel()
|
||||
watch(step, (val) => {
|
||||
let stepName = 'segmentation'
|
||||
if (val === 1) stepName = 'slideshow'
|
||||
if (val === 2) stepName = 'checklist'
|
||||
watch(showSegmentation, (val) => {
|
||||
mp.track('Onboarding Action', {
|
||||
type: 'action',
|
||||
name: 'step-activation',
|
||||
step: val,
|
||||
stepName
|
||||
stepName: val ? 'slideshow' : 'segmentation'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
:class="isSmallerOrEqualSm ? 'bottom-0 left-0 w-screen' : ''"
|
||||
:style="isSmallerOrEqualSm ? undefined : item.style"
|
||||
:show-controls="item.showControls"
|
||||
:disable-next="hasAddedOverlay"
|
||||
@skip="finishSlideshow()"
|
||||
>
|
||||
<Component :is="tourItems[index]" />
|
||||
<Component :is="tourItems[index]" @has-added-overlay="hasAddedOverlay = true" />
|
||||
</TourComment>
|
||||
<!-- In case the bubble is closed by the user, we need to display something -->
|
||||
<Transition
|
||||
@@ -76,6 +77,7 @@ const tourItems = [FirstTip, BasicViewerNavigation, OverlayModel /* , LastTip */
|
||||
const slideshowItems = ref(slideshowItemsRaw.slice(0, tourItems.length))
|
||||
provide('slideshowItems', slideshowItems)
|
||||
|
||||
const hasAddedOverlay = ref(false)
|
||||
const lastOpenIndex = ref(0)
|
||||
const mp = useMixpanel()
|
||||
|
||||
|
||||
@@ -4,18 +4,16 @@
|
||||
<p class="text-sm">
|
||||
Speckle allows you to load multiple models in the same viewer.
|
||||
</p>
|
||||
<p class="text-sm mt-2">
|
||||
<p class="text-sm mt-3">
|
||||
<span v-show="!hasAddedOverlay">
|
||||
<FormButton
|
||||
link
|
||||
text
|
||||
:icon-right="hasAddedOverlay ? CheckIcon : null"
|
||||
color="outline"
|
||||
:icon-right="hasAddedOverlay ? CheckIcon : PlusIcon"
|
||||
:disabled="hasAddedOverlay"
|
||||
@click="addOverlay()"
|
||||
>
|
||||
Click here
|
||||
Add another model
|
||||
</FormButton>
|
||||
to give it a try!
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
@@ -31,7 +29,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { CheckIcon } from '@heroicons/vue/24/solid'
|
||||
import { CheckIcon, PlusIcon } from '@heroicons/vue/24/solid'
|
||||
import { SpeckleViewer } from '@speckle/shared'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { latestModelsQuery } from '~~/lib/projects/graphql/queries'
|
||||
@@ -42,6 +40,8 @@ import {
|
||||
|
||||
import { SECOND_MODEL_NAME } from '~~/lib/auth/composables/onboarding'
|
||||
|
||||
const emit = defineEmits(['hasAddedOverlay'])
|
||||
|
||||
const { items } = useInjectedViewerRequestedResources()
|
||||
const { project } = useInjectedViewerLoadedResources()
|
||||
const id = project.value?.id as string
|
||||
@@ -62,6 +62,7 @@ async function addOverlay() {
|
||||
])
|
||||
|
||||
hasAddedOverlay.value = true
|
||||
emit('hasAddedOverlay')
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
v-if="showTour"
|
||||
class="fixed w-full h-[100dvh] flex justify-center items-center pointer-events-none z-[100]"
|
||||
>
|
||||
<TourOnboarding />
|
||||
<TourOnboarding @complete="showTour = false" />
|
||||
</div>
|
||||
<!-- Viewer host -->
|
||||
<div
|
||||
|
||||
@@ -36,7 +36,7 @@ export const items = [
|
||||
}
|
||||
},
|
||||
{
|
||||
camPos: [-39.91711, 46.26069, 42.83686, -18.44162, 29.75982, 34.91624, 0, 1],
|
||||
camPos: [23.86779, 82.9541, 29.05586, -27.41942, 37.72358, 29.05586, 0, 1],
|
||||
style: {} as Partial<CSSProperties>,
|
||||
viewed: false,
|
||||
showControls: false,
|
||||
|
||||
Reference in New Issue
Block a user