Start UI Change
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
const auth = useAuthStore()
|
||||
const { has } = usePermission()
|
||||
|
||||
// Lokaler State für den Taschenrechner
|
||||
const showCalculator = ref(false)
|
||||
const tenantExtraModules = computed(() => {
|
||||
const modules = auth.activeTenantData?.extraModules
|
||||
return Array.isArray(modules) ? modules : []
|
||||
@@ -19,6 +23,17 @@ const isAdmin = computed(() => Boolean(auth.user?.is_admin))
|
||||
const tenantFeatures = computed(() => auth.activeTenantData?.features || {})
|
||||
const featureEnabled = (key) => tenantFeatures.value?.[key] !== false
|
||||
const visibleItems = (items) => items.filter(item => item && !item.disabled)
|
||||
const isRouteActive = (to) => {
|
||||
if (!to) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (to === '/') {
|
||||
return route.path === '/'
|
||||
}
|
||||
|
||||
return route.path === to || route.path.startsWith(`${to}/`)
|
||||
}
|
||||
|
||||
const links = computed(() => {
|
||||
const organisationChildren = [
|
||||
@@ -284,15 +299,13 @@ const links = computed(() => {
|
||||
label: pin.label,
|
||||
to: pin.link,
|
||||
icon: pin.icon,
|
||||
target: "_blank",
|
||||
pinned: true
|
||||
target: "_blank"
|
||||
}
|
||||
} else if (pin.type === "standardEntity") {
|
||||
return {
|
||||
label: pin.label,
|
||||
to: pin.datatype === "tasks" ? `/tasks/show/${pin.id}` : `/standardEntity/${pin.datatype}/show/${pin.id}`,
|
||||
icon: pin.icon,
|
||||
pinned: true
|
||||
icon: pin.icon
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -382,81 +395,80 @@ const links = computed(() => {
|
||||
])
|
||||
})
|
||||
|
||||
const accordionItems = computed(() =>
|
||||
links.value.filter(item => Array.isArray(item.children) && item.children.length > 0)
|
||||
)
|
||||
const navItems = computed(() =>
|
||||
links.value
|
||||
.filter(Boolean)
|
||||
.map((item, index) => {
|
||||
const children = Array.isArray(item.children)
|
||||
? item.children.map((child, childIndex) => ({
|
||||
...child,
|
||||
value: child.id || child.label || `${index}-${childIndex}`,
|
||||
active: isRouteActive(child.to)
|
||||
}))
|
||||
: undefined
|
||||
|
||||
const buttonItems = computed(() =>
|
||||
links.value.filter(item => !item.children || item.children.length === 0)
|
||||
const active = item.active || isRouteActive(item.to) || Boolean(children?.some(child => child.active))
|
||||
|
||||
return {
|
||||
...item,
|
||||
children,
|
||||
value: item.id || item.label || String(index),
|
||||
defaultOpen: item.defaultOpen || active,
|
||||
active,
|
||||
tooltip: true,
|
||||
popover: true,
|
||||
trailingIcon: children?.length ? undefined : ''
|
||||
}
|
||||
})
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-1">
|
||||
<UButton
|
||||
v-for="item in buttonItems"
|
||||
:key="item.label"
|
||||
variant="ghost"
|
||||
:color="(item.to && route.path === item.to) ? 'primary' : (item.pinned ? 'amber' : 'gray')"
|
||||
:icon="item.pinned ? 'i-heroicons-star' : item.icon"
|
||||
class="w-full"
|
||||
:to="item.to"
|
||||
:target="item.target"
|
||||
@click="item.click ? item.click() : null"
|
||||
>
|
||||
<UIcon
|
||||
v-if="item.pinned"
|
||||
:name="item.icon"
|
||||
class="w-5 h-5 me-2"
|
||||
/>
|
||||
{{ item.label }}
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<UDivider class="my-2"/>
|
||||
|
||||
<UAccordion
|
||||
:items="accordionItems"
|
||||
:multiple="false"
|
||||
class="mt-2"
|
||||
<UNavigationMenu
|
||||
:items="navItems"
|
||||
orientation="vertical"
|
||||
:collapsed="props.collapsed"
|
||||
tooltip
|
||||
popover
|
||||
color="neutral"
|
||||
highlight
|
||||
highlight-color="primary"
|
||||
class="w-full"
|
||||
:ui="{
|
||||
root: 'w-full',
|
||||
list: 'space-y-1',
|
||||
link: 'min-w-0 rounded-lg px-2.5 py-2',
|
||||
linkLeadingIcon: 'size-5 shrink-0',
|
||||
linkLabel: 'truncate',
|
||||
childList: 'ms-0 space-y-1 border-l border-default ps-3',
|
||||
childLink: 'min-w-0 rounded-lg px-2 py-1.5',
|
||||
childLinkLabel: 'truncate'
|
||||
}"
|
||||
>
|
||||
<template #default="{ item, open }">
|
||||
<UButton
|
||||
variant="ghost"
|
||||
:color="(item.children?.some(c => route.path.includes(c.to))) ? 'primary' : 'gray'"
|
||||
:icon="item.icon"
|
||||
class="w-full"
|
||||
<template #item-leading="{ item, active }">
|
||||
<UIcon
|
||||
v-if="item.icon"
|
||||
:name="item.icon"
|
||||
class="size-5 shrink-0"
|
||||
:class="active ? 'text-primary' : 'text-muted'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #item-trailing="{ item, active }">
|
||||
<UBadge
|
||||
v-if="item.badge && !props.collapsed"
|
||||
color="primary"
|
||||
variant="soft"
|
||||
size="xs"
|
||||
>
|
||||
{{ item.label }}
|
||||
<template #trailing>
|
||||
<UIcon
|
||||
name="i-heroicons-chevron-right-20-solid"
|
||||
class="w-5 h-5 ms-auto transform transition-transform duration-200"
|
||||
:class="[open && 'rotate-90']"
|
||||
/>
|
||||
</template>
|
||||
</UButton>
|
||||
{{ item.badge }}
|
||||
</UBadge>
|
||||
<UIcon
|
||||
v-else-if="item.children?.length"
|
||||
name="i-heroicons-chevron-down-20-solid"
|
||||
class="size-4 shrink-0 transition-transform"
|
||||
:class="active ? 'text-primary' : 'text-muted'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #item="{ item }">
|
||||
<div class="flex flex-col">
|
||||
<UButton
|
||||
v-for="child in item.children"
|
||||
:key="child.label"
|
||||
variant="ghost"
|
||||
:color="child.to === route.path ? 'primary' : 'gray'"
|
||||
:icon="child.icon"
|
||||
class="ml-4"
|
||||
:to="child.to"
|
||||
:target="child.target"
|
||||
:disabled="child.disabled"
|
||||
@click="child.click ? child.click() : null"
|
||||
>
|
||||
{{ child.label }}
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
</UAccordion>
|
||||
|
||||
<Calculator v-if="showCalculator" v-model="showCalculator"/>
|
||||
</UNavigationMenu>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user