refactor of menus
begin work on settings
This commit is contained in:
@@ -40,6 +40,7 @@ const display = ref(null)
|
||||
const hasPageLoader = ref(false)
|
||||
const isOpen = ref(false)
|
||||
const hasApps = ref(false)
|
||||
const openerHover = ref(false)
|
||||
|
||||
const toggleMenu = (value) => {
|
||||
isOpen.value = value
|
||||
@@ -78,6 +79,10 @@ const createOpener = () => {
|
||||
}
|
||||
|
||||
opener.addEventListener('click', () => toggleMenu(true), true)
|
||||
|
||||
if (openerHover.value) {
|
||||
opener.addEventListener('mouseenter', () => toggleMenu(true), true)
|
||||
}
|
||||
}
|
||||
|
||||
const createLoader = () => {
|
||||
@@ -111,6 +116,7 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
hasPageLoader.value = config.value['loader-enabled']
|
||||
openerHover.value = config.value['opener-hover']
|
||||
|
||||
if (hasApps.value) {
|
||||
createOpener()
|
||||
|
||||
@@ -77,10 +77,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, useTemplateRef, onMounted } from 'vue'
|
||||
import { ref, useTemplateRef, onMounted, watch } from 'vue'
|
||||
import { useNavStore } from '../store/nav.js'
|
||||
import { useConfigStore } from '../store/config.js'
|
||||
import { getActiveAppId } from '../lib/app.js'
|
||||
import { focusActiveApp } from '../lib/menu.js'
|
||||
import { containsAppsMatchingSearch, isAppMatchingSearch } from '../lib/search.js'
|
||||
|
||||
import OpenerButton from '../components/OpenerButton'
|
||||
@@ -108,6 +109,12 @@ const openerHover = ref(false)
|
||||
const menu = useTemplateRef('menu')
|
||||
const isTouchDevice = window.matchMedia('(pointer: coarse)').matches
|
||||
|
||||
watch(() => open, (val) => {
|
||||
if (val) {
|
||||
focusActiveApp(menu.value)
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const config = await configStore.getConfig()
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
ref="menu"
|
||||
>
|
||||
<div
|
||||
v-if="settings || !openerHover || (!avatar && !alwaysDisplayed && logo) || avatar"
|
||||
class="side-menu-header"
|
||||
v-if="settings || displayLogo || open || !openerHover"
|
||||
>
|
||||
<SettingsButton
|
||||
v-if="settings && open"
|
||||
@@ -32,26 +32,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/>
|
||||
<AppSearch v-model="search" v-if="open" />
|
||||
<OpenerButton
|
||||
v-if="(!alwaysDisplayed && !openerHover) || isTouchDevice"
|
||||
v-if="!openerHover || isTouchDevice"
|
||||
@click="$emit('toggle')"
|
||||
/>
|
||||
<Logo
|
||||
v-if="!avatar && !alwaysDisplayed && logo"
|
||||
v-if="displayLogo"
|
||||
:classes="{ 'side-menu-logo': true, avatardiv: false }"
|
||||
:image="logo"
|
||||
:link="logoLink"
|
||||
/>
|
||||
<Logo
|
||||
v-if="avatar && !alwaysDisplayed"
|
||||
:classes="{ 'side-menu-logo': true, avatardiv: true }"
|
||||
:image="avatar"
|
||||
:image="useAvatarAsLogo ? avatar : logo"
|
||||
:link="logoLink"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
class="side-menu-apps-list"
|
||||
:class="{ 'side-menu-apps-list--with-settings': !!settings }"
|
||||
:class="{ 'side-menu-apps-list--with-logo': displayLogo }"
|
||||
>
|
||||
<template
|
||||
v-for="(app, key) in apps"
|
||||
@@ -59,7 +53,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
>
|
||||
<SideMenuApp
|
||||
v-if="isAppMatchingSearch(app, search)"
|
||||
:classes="{ 'side-menu-app': true, active: app.active }"
|
||||
:classes="{ 'side-menu-app': true, active: app.id === activeApp }"
|
||||
:icon="app.icon"
|
||||
:label="app.name"
|
||||
:href="app.href"
|
||||
@@ -74,7 +68,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { ref, useTemplateRef, onMounted, watch } from 'vue'
|
||||
import { useConfigStore } from '../store/config.js'
|
||||
import { useNavStore } from '../store/nav.js'
|
||||
import { focusActiveApp } from '../lib/menu.js'
|
||||
import { isAppMatchingSearch } from '../lib/search.js'
|
||||
import { getActiveAppId } from '../lib/app.js'
|
||||
|
||||
import OpenerButton from '../components/OpenerButton'
|
||||
import SettingsButton from '../components/SettingsButton'
|
||||
@@ -94,12 +90,15 @@ const navStore = useNavStore()
|
||||
const configStore = useConfigStore()
|
||||
const targetBlankApps = ref(null)
|
||||
const forceLightIcon = ref(null)
|
||||
const activeApp = ref(null)
|
||||
const avatar = ref(null)
|
||||
const logo = ref(null)
|
||||
const logoLink = ref(null)
|
||||
const settings = ref(null)
|
||||
const openerHover = ref(false)
|
||||
const alwaysDisplayed = ref(false)
|
||||
const displayLogo = ref(false)
|
||||
const useAvatarAsLogo = ref(false)
|
||||
const search = ref('')
|
||||
const apps = ref([])
|
||||
const menu = useTemplateRef('menu')
|
||||
@@ -109,6 +108,12 @@ watch(apps, (val) => {
|
||||
document.querySelector('html').classList.toggle('side-menu-always-displayed', alwaysDisplayed.value && val.length)
|
||||
})
|
||||
|
||||
watch(() => open, (val) => {
|
||||
if (val) {
|
||||
focusActiveApp(menu.value)
|
||||
}
|
||||
})
|
||||
|
||||
function getFiltredAndSortedApps(items, order, topMenuApps, topSideMenuApps) {
|
||||
const data = []
|
||||
|
||||
@@ -136,14 +141,22 @@ function getFiltredAndSortedApps(items, order, topMenuApps, topSideMenuApps) {
|
||||
onMounted(async () => {
|
||||
const config = await configStore.getConfig()
|
||||
|
||||
alwaysDisplayed.value = config['always-displayed']
|
||||
targetBlankApps.value = config['target-blank-apps']
|
||||
forceLightIcon.value = config['force-light-icon']
|
||||
|
||||
avatar.value = config['avatar']
|
||||
logo.value = config['logo']
|
||||
useAvatarAsLogo.value = config['use-avatar']
|
||||
displayLogo.value = config['display-logo'] && !alwaysDisplayed.value && (
|
||||
(!useAvatarAsLogo.value && logo.value) ||
|
||||
(useAvatarAsLogo.value && avatar.value)
|
||||
)
|
||||
|
||||
logoLink.value = config['logo-link']
|
||||
settings.value = config['settings']
|
||||
openerHover.value = config['opener-hover'] && !isTouchDevice
|
||||
alwaysDisplayed.value = config['always-displayed']
|
||||
activeApp.value = getActiveAppId()
|
||||
|
||||
apps.value = getFiltredAndSortedApps(await navStore.getApps(), config['apps-order'], config['top-menu-apps'], config['top-side-menu-apps'])
|
||||
|
||||
@@ -151,7 +164,7 @@ onMounted(async () => {
|
||||
menu.value.addEventListener('mouseleave', () => emit('close'))
|
||||
}
|
||||
|
||||
if (alwaysDisplayed.value) {
|
||||
if (alwaysDisplayed.value && openerHover.value) {
|
||||
menu.value.addEventListener('mouseenter', () => emit('open'))
|
||||
menu.value.addEventListener('mouseleave', () => emit('close'))
|
||||
}
|
||||
|
||||
@@ -81,10 +81,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, useTemplateRef, onMounted } from 'vue'
|
||||
import { ref, useTemplateRef, onMounted, watch } from 'vue'
|
||||
import { useNavStore } from '../store/nav.js'
|
||||
import { useConfigStore } from '../store/config.js'
|
||||
import { getActiveAppId } from '../lib/app.js'
|
||||
import { focusActiveApp } from '../lib/menu.js'
|
||||
import { containsAppsMatchingSearch, isAppMatchingSearch } from '../lib/search.js'
|
||||
|
||||
import OpenerButton from '../components/OpenerButton'
|
||||
@@ -113,6 +114,12 @@ const openerHover = ref(false)
|
||||
const menu = useTemplateRef('menu')
|
||||
const isTouchDevice = window.matchMedia('(pointer: coarse)').matches
|
||||
|
||||
watch(() => open, (val) => {
|
||||
if (val) {
|
||||
focusActiveApp(menu.value)
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const config = await configStore.getConfig()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user