Files
speckle-server/packages/frontend-2/components/dashboard/Sidebar.vue
T

171 lines
6.1 KiB
Vue

<!-- eslint-disable vuejs-accessibility/no-static-element-interactions -->
<!-- eslint-disable vuejs-accessibility/click-events-have-key-events -->
<template>
<div class="group h-full">
<template v-if="isLoggedIn">
<Portal to="mobile-navigation">
<div class="lg:hidden">
<FormButton
:color="isOpenMobile ? 'outline' : 'subtle'"
size="sm"
class="mt-px"
@click="isOpenMobile = !isOpenMobile"
>
<IconSidebar v-if="!isOpenMobile" class="h-4 w-4 -ml-1 -mr-1" />
<IconSidebarClose v-else class="h-4 w-4 -ml-1 -mr-1" />
</FormButton>
</div>
</Portal>
<div
v-keyboard-clickable
class="lg:hidden absolute inset-0 backdrop-blur-sm z-40 transition-all"
:class="isOpenMobile ? 'opacity-100' : 'opacity-0 pointer-events-none'"
@click="isOpenMobile = false"
/>
<div
class="absolute z-40 lg:static h-full flex w-[13rem] shrink-0 transition-all"
:class="isOpenMobile ? '' : '-translate-x-[13rem] lg:translate-x-0'"
>
<LayoutSidebar
class="border-r border-outline-3 px-2 pt-3 pb-2 bg-foundation-page"
>
<LayoutSidebarMenu>
<LayoutSidebarMenuGroup v-if="isWorkspacesEnabled" class="lg:hidden mb-4">
<HeaderWorkspaceSwitcher />
</LayoutSidebarMenuGroup>
<div class="flex flex-col gap-y-2 lg:gap-y-4">
<LayoutSidebarMenuGroup>
<NuxtLink :to="projectsLink" @click="isOpenMobile = false">
<LayoutSidebarMenuGroupItem
label="Projects"
:active="
route.name === 'workspaces-slug' || isActive(projectsRoute)
"
>
<template #icon>
<IconProjects class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
<NuxtLink :to="connectorsRoute" @click="isOpenMobile = false">
<LayoutSidebarMenuGroupItem
label="Connectors"
:active="isActive(connectorsRoute)"
>
<template #icon>
<IconConnectors class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
<NuxtLink :to="tutorialsRoute" @click="isOpenMobile = false">
<LayoutSidebarMenuGroupItem
label="Tutorials"
:active="isActive(tutorialsRoute)"
>
<template #icon>
<IconTutorials class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
</LayoutSidebarMenuGroup>
<LayoutSidebarMenuGroup title="Resources" collapsible>
<NuxtLink
to="https://speckle.community/"
target="_blank"
@click="isOpenMobile = false"
>
<LayoutSidebarMenuGroupItem label="Community forum" external>
<template #icon>
<IconCommunity class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
<div @click="openFeedbackDialog">
<LayoutSidebarMenuGroupItem label="Give us feedback">
<template #icon>
<IconFeedback class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</div>
<NuxtLink
to="https://speckle.guide/"
target="_blank"
@click="isOpenMobile = false"
>
<LayoutSidebarMenuGroupItem label="Documentation" external>
<template #icon>
<IconDocumentation class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
<NuxtLink
to="https://speckle.community/c/making-speckle/changelog"
target="_blank"
@click="isOpenMobile = false"
>
<LayoutSidebarMenuGroupItem label="Changelog" external>
<template #icon>
<IconChangelog class="size-4 text-foreground-2" />
</template>
</LayoutSidebarMenuGroupItem>
</NuxtLink>
</LayoutSidebarMenuGroup>
</div>
</LayoutSidebarMenu>
</LayoutSidebar>
</div>
</template>
<FeedbackDialog v-model:open="showFeedbackDialog" />
</div>
</template>
<script setup lang="ts">
import {
FormButton,
LayoutSidebar,
LayoutSidebarMenu,
LayoutSidebarMenuGroup,
LayoutSidebarMenuGroupItem
} from '@speckle/ui-components'
import {
projectsRoute,
connectorsRoute,
workspaceRoute,
tutorialsRoute
} from '~/lib/common/helpers/route'
import { useRoute } from 'vue-router'
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
import { useNavigation } from '~~/lib/navigation/composables/navigation'
const { isLoggedIn } = useActiveUser()
const isWorkspacesEnabled = useIsWorkspacesEnabled()
const route = useRoute()
const { activeWorkspaceSlug } = useNavigation()
const isOpenMobile = ref(false)
const showFeedbackDialog = ref(false)
const projectsLink = computed(() => {
return isWorkspacesEnabled.value
? activeWorkspaceSlug.value
? workspaceRoute(activeWorkspaceSlug.value)
: projectsRoute
: projectsRoute
})
const isActive = (...routes: string[]): boolean => {
return routes.some((routeTo) => route.path === routeTo)
}
const openFeedbackDialog = () => {
showFeedbackDialog.value = true
isOpenMobile.value = false
}
</script>