feat: Kategorie "Eigene Module" fuer selbst angelegte Eintraege
Tessera CI/CD / Lint & Type Check (push) Successful in 48s
Tessera CI/CD / Tests (push) Successful in 1m27s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 19s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m33s

CUSTOM_MODULE_CATEGORIES = MODULE_CATEGORIES + custom-modules; API prueft
dagegen, das Formular bietet sie an. Die Seitenleiste zeigt die Gruppe wie
jede Kategorie nur mit Eintrag und stellt sie immer ans Ende. Nutzerwunsch
29.09.; ohne Migration (category ist Freitext mit IsIn-Pruefung).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 11:24:56 +02:00
parent 00c2cfe2c9
commit 4ff9a239fd
10 changed files with 63 additions and 13 deletions
@@ -299,6 +299,32 @@ describe('Sidebar', () => {
expect(screen.getByText('Domain-Tools')).toBeInTheDocument();
});
it('Kategorie „Eigene Module“ steht zuletzt und nur, wenn ein Eintrag darin liegt', async () => {
mockCustomModules = [
customModule({ id: 'cm-1', category: 'custom-modules', name: 'Mein Wiki' }),
customModule({ id: 'cm-2', category: 'fleet', name: 'Tankkarte' }),
];
const Sidebar = await importSidebar();
const { unmount } = render(<Sidebar />);
await waitFor(() => {
expect(screen.getByText('Mein Wiki')).toBeInTheDocument();
});
const groups = Array.from(
screen.getByRole('group', { name: 'Kategorien' }).querySelectorAll(':scope > ul > li > button span.truncate'),
).map((n) => n.textContent);
expect(groups.at(-1)).toBe('custom-modules');
expect(groups).toContain('fleet');
unmount();
mockCustomModules = [customModule({ category: 'fleet' })];
render(<Sidebar />);
await waitFor(() => {
expect(screen.getByText('fleet')).toBeInTheDocument();
});
expect(screen.queryByText('custom-modules')).toBeNull();
});
it('eingebaute Module stehen innerhalb einer Kategorie vor eigenen', async () => {
mockCustomModules = [customModule({ category: 'Domain-Tools', name: 'Aaa Eigenes' })];
const Sidebar = await importSidebar();
+7 -2
View File
@@ -3,6 +3,7 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { CUSTOM_MODULE_CATEGORY } from '@tessera/shared';
import { useTranslations } from 'next-intl';
import { TesseraLogo } from '@/components/brand/tessera-logo';
import { useSidebarStore } from '@/lib/stores/sidebar-store';
@@ -192,11 +193,15 @@ export function Sidebar() {
categories.get(entry.category)!.push(entry);
}
if (!searchQuery) return Array.from(categories.entries());
// „Eigene Module“ steht immer zuletzt, die uebrigen in Fundreihenfolge.
const ordered = Array.from(categories.entries()).sort(
([a], [b]) => Number(a === CUSTOM_MODULE_CATEGORY) - Number(b === CUSTOM_MODULE_CATEGORY),
);
if (!searchQuery) return ordered;
const q = searchQuery.toLowerCase();
const result: [string, SidebarEntry[]][] = [];
for (const [cat, mods] of categories.entries()) {
for (const [cat, mods] of ordered) {
if (cat.toLowerCase().includes(q) || categoryLabel(cat).toLowerCase().includes(q)) {
result.push([cat, mods]);
} else {