generated from alphane/template
Initial commit
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<v-app-bar
|
||||
id="top"
|
||||
elevation="10"
|
||||
height="60"
|
||||
class="main-head pl-2"
|
||||
>
|
||||
<div class="mr-3">
|
||||
<AppLogo />
|
||||
</div>
|
||||
|
||||
<v-spacer />
|
||||
|
||||
<v-btn
|
||||
v-if="isSystemAdmin"
|
||||
icon
|
||||
variant="text"
|
||||
class="custom-hover-primary mr-2"
|
||||
size="small"
|
||||
title="AI Assistant"
|
||||
@click="$emit('toggle-ai-panel')"
|
||||
>
|
||||
<v-icon size="28">mdi-robot-outline</v-icon>
|
||||
</v-btn>
|
||||
<ProfileMenu />
|
||||
</v-app-bar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useCurrentUser from "@/use/use-current-user"
|
||||
|
||||
import AppLogo from "@/components/common/AppLogo.vue"
|
||||
import ProfileMenu from "@/components/layout/ProfileMenu.vue"
|
||||
|
||||
defineEmits<{
|
||||
"toggle-ai-panel": []
|
||||
}>()
|
||||
|
||||
const { isSystemAdmin } = useCurrentUser<true>()
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<v-navigation-drawer
|
||||
v-model="sidebarDrawer"
|
||||
left
|
||||
elevation="0"
|
||||
rail-width="75"
|
||||
app
|
||||
class="leftSidebar"
|
||||
:rail="sidebarMini"
|
||||
expand-on-hover
|
||||
width="256"
|
||||
>
|
||||
<div class="pa-2">
|
||||
<v-card
|
||||
v-if="currentUser"
|
||||
variant="outlined"
|
||||
style="overflow: hidden"
|
||||
>
|
||||
<v-card-text
|
||||
v-if="!sidebarMini"
|
||||
class="pa-2"
|
||||
>
|
||||
<div class="font-weight-bold">{{ currentUser.displayName }}</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
|
||||
<v-list class="d-none py-3 px-4">
|
||||
<v-list-subheader
|
||||
class="text-uppercase text-13 font-weight-semibold textPrimary d-flex align-items-center"
|
||||
>
|
||||
<span class="mini-icon">
|
||||
<IconDotsCircleHorizontal
|
||||
size="16"
|
||||
stroke-width="1.5"
|
||||
class="iconClass"
|
||||
/>
|
||||
</span>
|
||||
<span class="mini-text">Aircraft</span>
|
||||
</v-list-subheader>
|
||||
|
||||
<v-list-item
|
||||
v-scroll-to="{ el: '#top' }"
|
||||
:to="{}"
|
||||
rounded="pill"
|
||||
class="mb-1 px-3"
|
||||
>
|
||||
<template #prepend>
|
||||
<IconPointFilled
|
||||
size="24"
|
||||
class="dot mini-icon"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<span class="mini-text"> Y-CCAA</span>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IconDotsCircleHorizontal, IconPointFilled } from "@tabler/icons-vue"
|
||||
|
||||
import useCurrentUser from "@/use/use-current-user"
|
||||
import useInterface from "@/use/use-interface"
|
||||
|
||||
const { sidebarDrawer, sidebarMini } = useInterface()
|
||||
|
||||
const { currentUser } = useCurrentUser()
|
||||
</script>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<v-breadcrumbs
|
||||
class="flex-wrap"
|
||||
:items="breadcrumbsWithExactTrueByDefault"
|
||||
color=""
|
||||
>
|
||||
<template #title="{ item }">
|
||||
<transition
|
||||
name="breadcrumb-title-fade"
|
||||
mode="out-in"
|
||||
>
|
||||
<v-progress-circular
|
||||
v-if="isEmpty(item.title)"
|
||||
key="title-loader"
|
||||
size="16"
|
||||
color="secondary"
|
||||
width="1"
|
||||
indeterminate
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
key="title-text"
|
||||
>
|
||||
{{ item.title }}
|
||||
</span>
|
||||
</transition>
|
||||
</template>
|
||||
<template #divider>
|
||||
<v-icon>mdi-chevron-right</v-icon>
|
||||
</template>
|
||||
</v-breadcrumbs>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export { type Breadcrumb } from "@/use/use-breadcrumbs"
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { isEmpty } from "lodash"
|
||||
|
||||
import { type Breadcrumb } from "@/use/use-breadcrumbs"
|
||||
|
||||
const props = defineProps<{
|
||||
items: Breadcrumb[]
|
||||
}>()
|
||||
|
||||
// Changes https://vuetifyjs.com/en/components/breadcrumbs/ default behavior.
|
||||
// By default v-breadcrumbs will disable all crumbs up to the current page in a nested paths.
|
||||
// You can prevent this behavior by using exact: true on each applicable breadcrumb in the items array.
|
||||
const breadcrumbsWithExactTrueByDefault = computed(() =>
|
||||
props.items.map((item) => ({
|
||||
...item,
|
||||
title: item.title ?? "",
|
||||
exact: item.exact ?? true,
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.breadcrumb-title-fade-enter-active,
|
||||
.breadcrumb-title-fade-leave-active {
|
||||
transition: opacity 0.18s ease;
|
||||
}
|
||||
.breadcrumb-title-fade-enter-from,
|
||||
.breadcrumb-title-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<v-menu
|
||||
v-model="showMenu"
|
||||
:close-on-content-click="false"
|
||||
class="profile_popup"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
class="ml-2"
|
||||
variant="tonal"
|
||||
v-bind="props"
|
||||
icon
|
||||
:text="currentUserInitials"
|
||||
@click="showMenu = true"
|
||||
/>
|
||||
</template>
|
||||
<v-sheet
|
||||
rounded="md"
|
||||
width="360"
|
||||
elevation="11"
|
||||
>
|
||||
<div class="px-8 pt-3">
|
||||
<div class="d-flex align-center mt-4 pb-6">
|
||||
<div>
|
||||
<h6 class="text-h6 mb-n1">{{ currentUser.displayName }}</h6>
|
||||
<div class="d-flex align-center mt-2">
|
||||
<IconMail
|
||||
:size="18"
|
||||
:stroke-width="1.5"
|
||||
/>
|
||||
|
||||
<span class="text-subtitle-1 font-weight-regular textSecondary ml-2">{{
|
||||
currentUser.email
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<v-divider></v-divider>
|
||||
</div>
|
||||
|
||||
<v-list
|
||||
class="py-0 theme-list"
|
||||
lines="two"
|
||||
>
|
||||
<v-list-item
|
||||
class="py-4 px-8 custom-text-primary"
|
||||
:to="{
|
||||
name: 'ProfilePage',
|
||||
}"
|
||||
@click="closeMenu"
|
||||
>
|
||||
<template #prepend>
|
||||
<v-avatar color="info">
|
||||
<IconUserCircle></IconUserCircle>
|
||||
</v-avatar>
|
||||
</template>
|
||||
<div>
|
||||
<h6 class="text-subtitle-1 font-weight-semibold mb-2 custom-title">My Profile</h6>
|
||||
</div>
|
||||
<p class="text-subtitle-1 font-weight-regular textSecondary">Manage your information</p>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-if="isSystemAdmin"
|
||||
class="py-4 px-8 custom-text-primary"
|
||||
:to="{
|
||||
name: 'administration/AdministrationDashboardPage',
|
||||
}"
|
||||
@click="closeMenu"
|
||||
>
|
||||
<template #prepend>
|
||||
<v-avatar color="warning">
|
||||
<IconSettings></IconSettings>
|
||||
</v-avatar>
|
||||
</template>
|
||||
<div>
|
||||
<h6 class="text-subtitle-1 font-weight-semibold mb-2 custom-title">
|
||||
ROTYR System Administration
|
||||
</h6>
|
||||
</div>
|
||||
<p class="text-subtitle-1 font-weight-regular textSecondary">Manage this application</p>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="isSystemAdmin"
|
||||
class="py-4 px-8 custom-text-primary"
|
||||
:to="{
|
||||
name: 'StatusPage',
|
||||
}"
|
||||
@click="closeMenu"
|
||||
>
|
||||
<template #prepend>
|
||||
<v-avatar color="secondary">
|
||||
<IconClock />
|
||||
</v-avatar>
|
||||
</template>
|
||||
<div>
|
||||
<h6 class="text-subtitle-1 font-weight-semibold mb-2 custom-title">Version</h6>
|
||||
</div>
|
||||
<p class="text-subtitle-1 font-weight-regular textSecondary">
|
||||
{{ releaseTag || "2024.08.29" }}
|
||||
</p>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<div class="pt-4 pb-6 px-8 text-center">
|
||||
<v-btn
|
||||
variant="outlined"
|
||||
block
|
||||
@click="signOut"
|
||||
>Logout</v-btn
|
||||
>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-menu>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue"
|
||||
import { IconClock, IconMail, IconSettings, IconUserCircle } from "@tabler/icons-vue"
|
||||
import { useAuth0 } from "@auth0/auth0-vue"
|
||||
import { isEmpty, isNil } from "lodash"
|
||||
|
||||
import useCurrentUser from "@/use/use-current-user"
|
||||
import useStatus from "@/use/use-status"
|
||||
|
||||
const { logout } = useAuth0()
|
||||
const { currentUser, isSystemAdmin, reset: resetCurrentUser } = useCurrentUser<true>()
|
||||
const showMenu = ref(false)
|
||||
|
||||
const { releaseTag } = useStatus()
|
||||
|
||||
const currentUserInitials = computed(() => {
|
||||
if (isNil(currentUser.value)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const { firstName, lastName, email } = currentUser.value
|
||||
if (!isNil(firstName) && !isEmpty(firstName) && !isNil(lastName) && !isEmpty(lastName)) {
|
||||
const initials = [firstName, lastName].map((name) => name[0]?.toUpperCase()).join("")
|
||||
return initials
|
||||
}
|
||||
|
||||
const initials = email
|
||||
.split(".")
|
||||
.map((part) => part[0]?.toUpperCase())
|
||||
.join("")
|
||||
return initials
|
||||
})
|
||||
|
||||
function closeMenu() {
|
||||
showMenu.value = false
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
resetCurrentUser()
|
||||
|
||||
const returnTo = encodeURI(window.location.origin)
|
||||
return logout({ logoutParams: { returnTo } })
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<v-menu
|
||||
v-model="showMenu"
|
||||
:close-on-content-click="false"
|
||||
class="search_popup"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
icon
|
||||
variant="text"
|
||||
class="custom-hover-primary mr-2"
|
||||
size="small"
|
||||
v-bind="props"
|
||||
>
|
||||
<IconSearch :size="26" />
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-sheet
|
||||
width="360"
|
||||
elevation="11"
|
||||
rounded="md"
|
||||
>
|
||||
<v-form class="d-flex flex-column pa-5">
|
||||
<v-text-field
|
||||
v-model="search"
|
||||
placeholder="Search"
|
||||
color="primary"
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
clearable
|
||||
@click:clear="search = ''"
|
||||
/>
|
||||
<v-btn
|
||||
class="mt-2"
|
||||
color="primary"
|
||||
type="submit"
|
||||
block
|
||||
>
|
||||
<v-icon start>mdi-magnify</v-icon> Search
|
||||
</v-btn>
|
||||
</v-form>
|
||||
|
||||
<v-divider />
|
||||
<h5 class="text-h5 mt-4 px-5 pb-4">Recently Viewed</h5>
|
||||
<v-divider />
|
||||
</v-sheet>
|
||||
</v-menu>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
|
||||
import { IconSearch } from "@tabler/icons-vue"
|
||||
|
||||
const showMenu = ref(false)
|
||||
|
||||
const search = ref("")
|
||||
</script>
|
||||
Reference in New Issue
Block a user