ffplayout/frontend/components/HeaderMenu.vue

215 lines
8.1 KiB
Vue
Raw Permalink Normal View History

2020-04-15 12:10:34 -04:00
<template>
2024-09-25 01:48:31 -04:00
<div class="navbar bg-base-100 min-h-[52px] p-0 shadow-md">
2024-04-11 15:34:03 -04:00
<NuxtLink class="navbar-brand min-w-[46px] p-2" href="/">
<img src="~/assets/images/ffplayout-small.png" class="img-fluid" alt="Logo" width="30" height="30" />
2024-04-04 17:28:25 -04:00
</NuxtLink>
<EventStatus v-if="route.name?.toString().includes('player__')" class="z-10" />
2024-04-04 17:28:25 -04:00
<div class="navbar-end w-1/5 grow">
<label class="swap swap-rotate me-2 2sm:hidden">
<input type="checkbox" :checked="indexStore.darkMode" @change="toggleDarkTheme" />
2024-04-09 15:08:25 -04:00
<SvgIcon name="swap-on" classes="w-5 h-5" />
<SvgIcon name="swap-off" classes="w-5 h-5" />
2024-04-06 17:12:06 -04:00
</label>
<details ref="menuDropdown" tabindex="0" class="dropdown dropdown-end z-50">
<summary class="btn btn-ghost 2sm:hidden" @click="clickMenu()" @blur="blurMenu()">
2024-04-09 15:08:25 -04:00
<SvgIcon name="burger" classes="w-5 h-5" />
</summary>
2024-04-04 17:28:25 -04:00
<ul class="menu menu-sm dropdown-content mt-1 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
<template v-for="item in menuItems" :key="item.name">
<li
v-if="
item.label !== 'message' ||
(configStore.playout.text.add_text && !configStore.playout.text.text_from_filename)
"
class="bg-base-100 rounded-md"
>
<NuxtLink
:to="item.link"
class="h-[27px] text-base"
exact-active-class="is-active"
@click="closeMenu()"
>
<span>
{{ item.name }}
</span>
</NuxtLink>
</li>
</template>
<li v-if="configStore.channels.length > 1">
2024-04-06 17:12:06 -04:00
<details tabindex="0" @focusout="closeDropdown">
2024-04-04 17:28:25 -04:00
<summary>
2024-04-05 12:51:50 -04:00
<div class="h-[19px] text-base">
<span> {{ configStore.channels[configStore.i].name }} </span>
2024-04-05 12:51:50 -04:00
</div>
2024-04-04 17:28:25 -04:00
</summary>
<ul class="p-2">
<li v-for="(channel, index) in configStore.channels" :key="index">
2024-04-04 17:28:25 -04:00
<span>
<a class="dropdown-item cursor-pointer" @click="selectChannel(index)">{{
channel.name
}}</a>
2024-04-04 17:28:25 -04:00
</span>
</li>
</ul>
</details>
</li>
<li class="bg-base-100 rounded-md">
2024-04-09 15:08:25 -04:00
<button class="h-[27px] text-base" exactActiveClass="is-active" @click="logout()">
{{ t('button.logout') }}
2024-04-09 15:08:25 -04:00
</button>
2024-04-04 17:28:25 -04:00
</li>
</ul>
</details>
2024-04-04 17:28:25 -04:00
</div>
<div class="navbar-end hidden 2sm:flex w-4/5 min-w-[750px]">
2024-04-04 17:28:25 -04:00
<ul class="menu menu-sm menu-horizontal px-1">
<template v-for="item in menuItems" :key="item.name">
<li
v-if="
item.label !== 'message' ||
(configStore.playout.text.add_text && !configStore.playout.text.text_from_filename)
"
class="bg-base-100 rounded-md p-0"
2024-04-09 15:08:25 -04:00
>
<NuxtLink
:to="item.link"
class="px-2 h-[27px] relative text-base text-base-content"
active-class="is-active"
>
<span>
{{ item.name }}
</span>
</NuxtLink>
</li>
</template>
<li v-if="configStore.channels.length > 1">
2024-04-06 17:12:06 -04:00
<details tabindex="0" @focusout="closeDropdown">
2024-04-04 17:28:25 -04:00
<summary>
2024-04-05 12:51:50 -04:00
<div class="h-[19px] text-base">
<span> {{ configStore.channels[configStore.i].name }} </span>
2024-04-04 17:28:25 -04:00
</div>
</summary>
<ul class="p-2 bg-base-100 rounded-md !mt-1 w-36" tabindex="0">
<li v-for="(channel, index) in configStore.channels" :key="index">
<a class="dropdown-item cursor-pointer" @click="selectChannel(index)">
2024-04-06 17:12:06 -04:00
{{ channel.name }}
</a>
2023-01-11 04:54:25 -05:00
</li>
</ul>
2024-04-04 17:28:25 -04:00
</details>
</li>
<li class="bg-base-100 rounded-md p-0">
2024-04-11 15:34:03 -04:00
<button class="h-[27px] pt-[4px] text-base" @click="logout()">
{{ t('button.logout') }}
2024-04-11 15:34:03 -04:00
</button>
2024-04-06 17:12:06 -04:00
</li>
<li class="p-0">
<label class="swap swap-rotate">
<input type="checkbox" :checked="indexStore.darkMode" @change="toggleDarkTheme" />
2024-04-09 15:08:25 -04:00
<SvgIcon name="swap-on" classes="w-5 h-5" />
<SvgIcon name="swap-off" classes="w-5 h-5" />
2024-04-06 17:12:06 -04:00
</label>
2024-04-04 17:28:25 -04:00
</li>
</ul>
2020-04-15 12:10:34 -04:00
</div>
</div>
</template>
2023-01-11 04:54:25 -05:00
<script setup lang="ts">
2024-04-06 17:12:06 -04:00
const colorMode = useColorMode()
2024-04-11 15:34:03 -04:00
const { t } = useI18n()
const localePath = useLocalePath()
2024-04-29 03:35:26 -04:00
const route = useRoute()
2024-04-11 15:34:03 -04:00
const router = useRouter()
2023-01-11 04:54:25 -05:00
const authStore = useAuth()
const configStore = useConfig()
2024-04-06 17:12:06 -04:00
const indexStore = useIndex()
2020-04-15 12:10:34 -04:00
const menuDropdown = ref()
const isOpen = ref(false)
2024-04-04 17:28:25 -04:00
const menuItems = ref([
{ label: 'index', name: t('button.home'), link: localePath({ name: 'index' }) },
{ label: 'player', name: t('button.player'), link: localePath({ name: 'player' }) },
{ label: 'media', name: t('button.media'), link: localePath({ name: 'media' }) },
{ label: 'message', name: t('button.message'), link: localePath({ name: 'message' }) },
{ label: 'logging', name: t('button.logging'), link: localePath({ name: 'logging' }) },
{ label: 'configure', name: t('button.configure'), link: localePath({ name: 'configure' }) },
2024-04-04 17:28:25 -04:00
])
2024-04-06 17:12:06 -04:00
if (colorMode.value === 'dark') {
indexStore.darkMode = true
}
function closeMenu() {
setTimeout(() => {
isOpen.value = false
menuDropdown.value?.removeAttribute('open')
}, 200)
}
function clickMenu() {
isOpen.value = !isOpen.value
if (!isOpen.value) {
menuDropdown.value?.removeAttribute('open')
}
}
function blurMenu() {
if (isOpen.value) {
isOpen.value = !isOpen.value
} else {
setTimeout(() => {
menuDropdown.value?.removeAttribute('open')
}, 200)
}
}
2024-04-04 17:28:25 -04:00
function closeDropdown($event: any) {
setTimeout(() => {
$event.target.parentNode?.removeAttribute('open')
2024-04-04 17:28:25 -04:00
}, 200)
}
2023-01-11 04:54:25 -05:00
function logout() {
authStore.removeToken()
2024-04-11 15:34:03 -04:00
router.push(localePath({ name: 'index' }))
2023-01-11 04:54:25 -05:00
}
2023-01-11 04:54:25 -05:00
function selectChannel(index: number) {
configStore.i = index
if (authStore.role === 'GlobalAdmin') {
configStore.getAdvancedConfig()
}
2023-01-11 04:54:25 -05:00
configStore.getPlayoutConfig()
2020-04-15 12:10:34 -04:00
}
2024-04-06 17:12:06 -04:00
function toggleDarkTheme() {
indexStore.darkMode = !indexStore.darkMode
if (indexStore.darkMode) {
colorMode.preference = 'dark'
} else {
colorMode.preference = 'light'
}
}
2020-04-15 12:10:34 -04:00
</script>
2024-04-04 17:28:25 -04:00
<style lang="scss" scoped>
.is-active > span::after {
background: var(--my-accent);
position: relative;
2024-04-04 17:28:25 -04:00
left: 0px;
2023-01-11 04:54:25 -05:00
content: ' ';
2024-04-04 17:28:25 -04:00
width: inherit;
height: 2px;
2024-04-04 17:28:25 -04:00
color: red;
display: block;
2024-04-04 17:28:25 -04:00
border-radius: 0.15em;
2023-01-11 04:54:25 -05:00
}
2020-04-15 12:10:34 -04:00
</style>