KI-AGENT: Chaträume sortieren und Matrix-Setup verschieben

This commit is contained in:
2026-05-19 08:31:40 +02:00
parent 5b3445c2dc
commit 0fb469c9b0
2 changed files with 88 additions and 69 deletions

View File

@@ -80,11 +80,6 @@ const links = computed(() => {
to: "/communication/chat", to: "/communication/chat",
icon: "i-heroicons-chat-bubble-left-right" icon: "i-heroicons-chat-bubble-left-right"
}, },
{
label: "Matrix-Setup",
to: "/communication",
icon: "i-heroicons-cog-6-tooth"
},
featureEnabled("helpdesk") ? { featureEnabled("helpdesk") ? {
label: "Helpdesk", label: "Helpdesk",
to: "/helpdesk", to: "/helpdesk",
@@ -332,6 +327,11 @@ const links = computed(() => {
to: "/settings/tenant", to: "/settings/tenant",
icon: "i-heroicons-building-office", icon: "i-heroicons-building-office",
} : null, } : null,
{
label: "Matrix-Setup",
to: "/communication",
icon: "i-heroicons-chat-bubble-left-right",
},
featureEnabled("export") ? { featureEnabled("export") ? {
label: "Export", label: "Export",
to: "/export", to: "/export",

View File

@@ -112,6 +112,10 @@ const roomCreateKeyPreview = computed(() =>
normalizeRoomKey(roomCreateForm.value.key || roomCreateForm.value.name) normalizeRoomKey(roomCreateForm.value.key || roomCreateForm.value.name)
) )
const sortRoomsByName = (roomList) => [...roomList].sort((first, second) =>
String(first.name || "").localeCompare(String(second.name || ""), "de", { sensitivity: "base" })
)
const rooms = computed(() => { const rooms = computed(() => {
const baseRooms = matrixRooms.value const baseRooms = matrixRooms.value
.filter((room) => !["project", "direct"].includes(room.type)) .filter((room) => !["project", "direct"].includes(room.type))
@@ -138,9 +142,31 @@ const rooms = computed(() => {
provisionEndpoint: `/api/communication/matrix/direct-rooms/${encodeURIComponent(room.userId)}/provision` provisionEndpoint: `/api/communication/matrix/direct-rooms/${encodeURIComponent(room.userId)}/provision`
})) }))
return [...baseRooms, ...projectRooms, ...directRooms] return [
...sortRoomsByName(baseRooms),
...sortRoomsByName(projectRooms),
...sortRoomsByName(directRooms)
]
}) })
const groupedRooms = computed(() => [
{
key: "rooms",
label: "Räume",
rooms: rooms.value.filter((room) => room.group === "Räume")
},
{
key: "projects",
label: "Projekte",
rooms: rooms.value.filter((room) => room.group === "Projekte")
},
{
key: "direct",
label: "Direktnachrichten",
rooms: rooms.value.filter((room) => room.group === "Direkt")
}
].filter((group) => group.rooms.length > 0))
const normalizeRoomKey = (value) => { const normalizeRoomKey = (value) => {
const normalized = String(value || "") const normalized = String(value || "")
.toLowerCase() .toLowerCase()
@@ -919,63 +945,63 @@ onBeforeUnmount(() => {
</form> </form>
</div> </div>
<div class="flex-1 overflow-y-auto p-3"> <div class="flex-1 space-y-4 overflow-y-auto p-3">
<button <section
v-for="room in rooms" v-for="group in groupedRooms"
:key="room.key" :key="group.key"
type="button" class="space-y-1"
class="mb-1 flex w-full items-center gap-3 rounded-md px-3 py-2 text-left transition"
:class="[
room.disabled ? 'cursor-not-allowed opacity-50' : 'text-highlighted hover:bg-muted',
room.key === activeRoomKey ? 'bg-muted ring-1 ring-primary/20' : ''
]"
:disabled="room.disabled"
@click="setActiveRoom(room)"
> >
<span class="flex size-9 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary"> <div class="flex items-center justify-between px-2">
<UIcon :name="room.icon || 'i-heroicons-chat-bubble-left-right'" class="size-5" /> <p class="text-[11px] font-semibold uppercase tracking-wide text-muted">
</span> {{ group.label }}
<span class="min-w-0 flex-1"> </p>
<span class="block truncate text-sm font-medium">{{ room.name }}</span> <span class="text-[11px] text-muted">{{ group.rooms.length }}</span>
<span class="block truncate text-xs text-muted">{{ room.description }}</span> </div>
</span> <button
<UBadge v-for="room in group.rooms"
v-if="roomProvisioningKey === room.key" :key="room.key"
color="primary" type="button"
variant="soft" class="flex w-full items-center gap-3 rounded-md px-3 py-2 text-left transition"
size="xs" :class="[
room.disabled ? 'cursor-not-allowed opacity-50' : 'text-highlighted hover:bg-muted',
room.key === activeRoomKey ? 'bg-muted ring-1 ring-primary/20' : ''
]"
:disabled="room.disabled"
@click="setActiveRoom(room)"
> >
lädt <span class="flex size-9 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary">
</UBadge> <UIcon :name="room.icon || 'i-heroicons-chat-bubble-left-right'" class="size-5" />
<UBadge </span>
v-else-if="room.exists" <span class="min-w-0 flex-1">
color="success" <span class="block truncate text-sm font-medium">{{ room.name }}</span>
variant="soft" <span class="block truncate text-xs text-muted">{{ room.description }}</span>
size="xs" </span>
> <UBadge
aktiv v-if="roomProvisioningKey === room.key"
</UBadge> color="primary"
<UBadge variant="soft"
v-else-if="!room.disabled" size="xs"
color="neutral" >
variant="soft" lädt
size="xs" </UBadge>
> <UBadge
offen v-else-if="room.exists"
</UBadge> color="success"
</button> variant="soft"
</div> size="xs"
>
<div class="border-t border-default p-3"> aktiv
<UButton </UBadge>
to="/communication" <UBadge
icon="i-heroicons-cog-6-tooth" v-else-if="!room.disabled"
color="neutral" color="neutral"
variant="outline" variant="soft"
block size="xs"
> >
Matrix-Setup offen
</UButton> </UBadge>
</button>
</section>
</div> </div>
</aside> </aside>
@@ -1020,13 +1046,6 @@ onBeforeUnmount(() => {
:disabled="!canStartMatrixCall" :disabled="!canStartMatrixCall"
@click="openMatrixCall('video')" @click="openMatrixCall('video')"
/> />
<UButton
class="lg:hidden"
to="/communication"
icon="i-heroicons-cog-6-tooth"
color="neutral"
variant="outline"
/>
<UButton <UButton
class="lg:hidden" class="lg:hidden"
icon="i-heroicons-plus" icon="i-heroicons-plus"
@@ -1050,7 +1069,7 @@ onBeforeUnmount(() => {
<div class="border-b border-default bg-default p-3 lg:hidden"> <div class="border-b border-default bg-default p-3 lg:hidden">
<div class="flex gap-2 overflow-x-auto pb-1"> <div class="flex gap-2 overflow-x-auto pb-1">
<button <button
v-for="room in rooms" v-for="room in rooms"
:key="room.key" :key="room.key"
type="button" type="button"