feat: app switcher
This commit is contained in:
67
frontend/src/components/Apps.vue
Normal file
67
frontend/src/components/Apps.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<Popover placement="right-start" class="flex w-full">
|
||||
<template #target="{ togglePopover }">
|
||||
<button
|
||||
:class="[
|
||||
'group w-full flex h-7 items-center justify-between rounded px-2 text-base text-gray-800 hover:bg-gray-100',
|
||||
]"
|
||||
@click.prevent="togglePopover()"
|
||||
>
|
||||
<div class="flex gap-2">
|
||||
<LayoutGrid class="size-4 stroke-1.5" />
|
||||
<span class="whitespace-nowrap">
|
||||
{{ __('Apps') }}
|
||||
</span>
|
||||
</div>
|
||||
<ChevronRight class="h-4 w-4 stroke-1.5" />
|
||||
</button>
|
||||
</template>
|
||||
<template #body>
|
||||
<div
|
||||
class="grid grid-cols-3 justify-between mx-3 p-2 rounded-lg border border-gray-100 bg-white shadow-xl"
|
||||
>
|
||||
<div v-for="app in apps.data" key="name">
|
||||
<a
|
||||
:href="app.route"
|
||||
class="flex flex-col gap-1.5 rounded justify-center items-center py-2 px-3 hover:bg-gray-100"
|
||||
>
|
||||
<img class="size-8" :src="app.logo" />
|
||||
<div class="text-sm" @click="app.onClick">
|
||||
{{ app.title }}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popover>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Popover, createResource } from 'frappe-ui'
|
||||
import { LayoutGrid, ChevronRight } from 'lucide-vue-next';
|
||||
|
||||
const apps = createResource({
|
||||
url: 'frappe.apps.get_apps',
|
||||
cache: 'apps',
|
||||
auto: true,
|
||||
transform: (data) => {
|
||||
let _apps = [
|
||||
{
|
||||
name: 'frappe',
|
||||
logo: '/assets/lms/images/desk.png',
|
||||
title: __('Desk'),
|
||||
route: '/app',
|
||||
},
|
||||
]
|
||||
data.map((app) => {
|
||||
if (app.name === 'lms') return
|
||||
_apps.push({
|
||||
name: app.name,
|
||||
logo: app.logo,
|
||||
title: __(app.title),
|
||||
route: app.route,
|
||||
})
|
||||
})
|
||||
return _apps
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -66,6 +66,7 @@
|
||||
import LMSLogo from '@/components/Icons/LMSLogo.vue'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import Apps from '@/components/Apps.vue'
|
||||
import {
|
||||
ChevronDown,
|
||||
LogIn,
|
||||
@@ -77,7 +78,7 @@ import {
|
||||
import { useRouter } from 'vue-router'
|
||||
import { convertToTitleCase } from '../utils'
|
||||
import { usersStore } from '@/stores/user'
|
||||
import { ref } from 'vue'
|
||||
import { ref, markRaw } from 'vue'
|
||||
import SettingsModal from '@/components/Modals/Settings.vue'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -105,11 +106,7 @@ const userDropdownOptions = [
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: ArrowRightLeft,
|
||||
label: 'Switch to Desk',
|
||||
onClick: () => {
|
||||
window.location.href = '/app'
|
||||
},
|
||||
component: markRaw(Apps),
|
||||
condition: () => {
|
||||
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||
let system_user = cookies.get('system_user')
|
||||
|
||||
Reference in New Issue
Block a user