ui generic rendering - base
This commit is contained in:
parent
5b83bc48b8
commit
d0185448ab
6 changed files with 1537 additions and 0 deletions
|
|
@ -27,6 +27,7 @@ Lade immer zuerst diese Datei. Dann gezielt die passende(n) Referenz-Datei(en).
|
|||
| Billing & Subscriptions | b-reference/platform-core/billing.md | Abrechnung, Prepaid, State Machine |
|
||||
| Google Voice (STT/TTS) | b-reference/platform-core/voice-google.md | VoiceObjects, ConnectorGoogleSpeech, `/voice-google/stt/*`, CommCoach vs Teamsbot vs Agent |
|
||||
| Frontend Nyla | b-reference/ui-nyla/architecture.md | UI-Seiten, Komponenten, Hooks, Routing |
|
||||
| Layout-System (StackLayout, Panel, LayoutTabs, ViewStack) | b-reference/ui-nyla/layout.md | Scroll-Vertrag, Panel-Varianten, Seiten-Aufbau-Muster, Migrations-Checkliste |
|
||||
| FormGenerator (Table, Form, Tree, Report) | b-reference/ui-nyla/formgenerator.md | Generische UI-Komponenten, Provider-Pattern, API-Anbindung |
|
||||
| Private LLM | b-reference/service-llm-private/architecture.md | Internes LLM, Neutralisierung |
|
||||
| Teams Bot | b-reference/teams-bot/architecture.md | Meeting-Bot, Browser-Bot WebSocket, Director Prompts (Hybrid Agent-Routing), MeetingModule + 5-Tab-UI, Dashboard-SSE, Live-Session-SSE + MFA |
|
||||
|
|
|
|||
372
b-reference/ui-nyla/layout.md
Normal file
372
b-reference/ui-nyla/layout.md
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
<!-- status: canonical -->
|
||||
<!-- lastReviewed: 2026-06-10 -->
|
||||
<!-- verifiedAgainst: ui-nyla Layout-Primitives (StackLayout, Panel, LayoutTabs, ViewStack, useScrollMode) -->
|
||||
|
||||
# Layout-System -- Referenz
|
||||
|
||||
## Uebersicht
|
||||
|
||||
Das Layout-System definiert, wie jede Seite in ui-nyla strukturiert wird. Es ersetzt das manuelle Pattern (`adminPage`/`adminPageFill`/`pageHeader`/`tableContainer` aus `Admin.module.css`) und alle Ad-hoc-Tab-Implementierungen durch ein einheitliches Komponentensystem.
|
||||
|
||||
Quell-Plan: `pagelayout_component_system_fd9fde3a.plan.md` (v3)
|
||||
|
||||
| Komponente | Datei | Zweck |
|
||||
|------------|-------|-------|
|
||||
| `StackLayout` | `components/Layout/StackLayout.tsx` | Seiten-Container mit Slots (Header, Toolbar, Tabs, Body, Footer) |
|
||||
| `Panel` | `components/Layout/Panel.tsx` | Typisierte Region (Card, Table, Dashboard, Toolbar, Editor, Wizard) mit Collapse/Expand |
|
||||
| `LayoutTabs` | `components/Layout/LayoutTabs.tsx` | Einziges Tab-System, URL als Source-of-Truth |
|
||||
| `ViewStack` | `components/Layout/ViewStack.tsx` | Master-Detail-Navigation (list/catalog/detail via URL) |
|
||||
| `useScrollMode` | `hooks/useScrollMode.ts` | Scroll-Modus-Erkennung (bounded/document) |
|
||||
|
||||
## Begriffe (WICHTIG, nicht verwechseln)
|
||||
|
||||
Drei verschiedene Konzepte, die sauber getrennt werden muessen:
|
||||
|
||||
| Begriff | Anzahl | Werte | Bedeutung |
|
||||
|---------|--------|-------|-----------|
|
||||
| **Slot** | 5 | Header, Toolbar, Tabs, Body, Footer | Benannte Bereiche des `StackLayout`-Seitenrahmens (Compound-Components, z.B. `<StackLayout.Body>`) |
|
||||
| **StackLayout-Variant** | 4 | table, scroll, form, dashboard | Scroll-Verhalten der gesamten Seite (Prop `variant` an `StackLayout`) |
|
||||
| **Region** | beliebig | — | Ein `Panel`-Inhaltsblock im Body. Das ist der collapsible/expandable Block, den der User sieht. |
|
||||
| **Regionstyp** | 6 | card, table, dashboard, toolbar, editor, wizard | Die Variante einer Region (Prop `variant` an `Panel`) |
|
||||
|
||||
Merksatz:
|
||||
- Eine **Seite** = ein `StackLayout` (mit `variant` fuer Scroll) und seinen **Slots**.
|
||||
- Jeder **Inhaltsblock** im Body = eine **Region** (ein `Panel` mit `variant` = Regionstyp).
|
||||
- `toolbar` existiert sowohl als Slot (`StackLayout.Toolbar`) als auch als Regionstyp (`Panel variant="toolbar"`). In der Praxis werden Filter-/Action-Bars als **Region** (`Panel variant="toolbar"`) im Body platziert; der Slot `StackLayout.Toolbar` ist optional fuer seitenweite Toolbars.
|
||||
|
||||
## Architektur-Prinzipien
|
||||
|
||||
1. **URL ist Source-of-Truth** fuer Navigation (aktiver Tab, aktive View, entityId). Kein `useState` fuer Tabs.
|
||||
2. **Jeder Seiteninhalt ist eine Region** (Panel mit Variant). Generische Aenderungen an einem Regionstyp wirken systemweit.
|
||||
3. **Keine Fallbacks**: Fehlender Kontext = Error, nicht stiller Default.
|
||||
4. **Kein RBAC im UI**: Sichtbarkeit via Backend-Flags.
|
||||
5. **Persistence ist pluggable**: Panel-Collapse in localStorage, Navigation in URL, Daten in DB.
|
||||
|
||||
## Scroll-Vertrag
|
||||
|
||||
### Problem
|
||||
|
||||
Die Layout-Kette ist durchgehend `overflow:hidden` mit `flex-shrink:0` fuer Chrome-Bereiche. Auf kleinen Viewports fuellt der Header die Seite, die Tabelle wird unbedienbar.
|
||||
|
||||
### Loesung: scrollMode-Zustandsmaschine
|
||||
|
||||
| Modus | Bedingung | Verhalten |
|
||||
|-------|-----------|-----------|
|
||||
| `bounded` | Viewport > 1024px Breite UND > 500px Hoehe | `overflow:hidden`-Kette intakt. Tabelle scrollt intern. Header bleibt sichtbar. |
|
||||
| `document` | Viewport <= 1024px ODER <= 500px Hoehe | `overflow:visible`-Kette. Seite scrollt als Dokument. Header scrollt weg. Tabelle waechst natuerlich. |
|
||||
|
||||
### Mechanismus
|
||||
|
||||
Hook `useScrollMode()` setzt `document.documentElement.dataset.scrollMode`. CSS-Module nutzen `:global(html[data-scroll-mode="document"])` als Selektor-Prefix.
|
||||
|
||||
```tsx
|
||||
import { useScrollMode } from '../../hooks/useScrollMode';
|
||||
|
||||
const MyPage = () => {
|
||||
const scrollMode = useScrollMode();
|
||||
// scrollMode wird automatisch auf StackLayout propagiert
|
||||
return <StackLayout variant="table">...</StackLayout>;
|
||||
};
|
||||
```
|
||||
|
||||
### Layout-Kette (verifiziert)
|
||||
|
||||
```
|
||||
MainLayout.mainLayout height:100dvh; overflow:hidden
|
||||
MainLayout.content overflow:hidden (desktop) / auto (mobile)
|
||||
MainLayout.outletShell overflow-y:auto
|
||||
FeatureLayout.featureContent overflow:hidden; flex:1
|
||||
FeatureView.viewContent overflow:auto; padding:1.5rem
|
||||
StackLayout root data-scroll-mode + data-variant
|
||||
Panel data-variant (card|table|dashboard|toolbar|editor|wizard)
|
||||
FormGeneratorTable height:100%; flex:1; overflow:hidden
|
||||
```
|
||||
|
||||
## StackLayout
|
||||
|
||||
Container fuer eine gesamte Seite oder einen Tab-Inhalt. Compound-Component-Pattern mit benannten **Slots**.
|
||||
|
||||
### Slots
|
||||
|
||||
| Slot | Zweck | Beispiel |
|
||||
|------|-------|---------|
|
||||
| `Header` | Seitentitel, Breadcrumb | Immer sichtbar |
|
||||
| `Toolbar` | Seitenweite Filter, Actions | Kontextbezogen (optional) |
|
||||
| `Tabs` | LayoutTabs-Container | Tab-Navigation |
|
||||
| `Body` | Hauptinhalt — enthaelt die Regionen (Panels) | Tabelle, Formular, Dashboard |
|
||||
| `Footer` | Status, Aktionen | Optional |
|
||||
|
||||
### StackLayout-Varianten (Scroll-Verhalten)
|
||||
|
||||
| Variant | Body-Verhalten |
|
||||
|---------|---------------|
|
||||
| `table` | flex:1, min-height:0, bounded scroll |
|
||||
| `scroll` | Normaler Scroll (Standard) |
|
||||
| `form` | Scroll mit Padding |
|
||||
| `dashboard` | Grid-freundlich, natuerliche Hoehe |
|
||||
|
||||
### Beispiel: Tabellen-Seite
|
||||
|
||||
```tsx
|
||||
<StackLayout variant="table">
|
||||
<StackLayout.Header>
|
||||
<h2>Benutzer</h2>
|
||||
</StackLayout.Header>
|
||||
<StackLayout.Body>
|
||||
<Panel variant="toolbar">
|
||||
<FilterBar />
|
||||
</Panel>
|
||||
<Panel variant="table" title="Benutzerliste" collapsible>
|
||||
<FormGeneratorTable ... />
|
||||
</Panel>
|
||||
</StackLayout.Body>
|
||||
</StackLayout>
|
||||
```
|
||||
|
||||
## Panel (Region)
|
||||
|
||||
Typisierter Container fuer jeden Inhaltsblock. Jede Panel-Instanz hat einen `variant`, der das Layout-Verhalten bestimmt.
|
||||
|
||||
### Props
|
||||
|
||||
| Prop | Typ | Default | Beschreibung |
|
||||
|------|-----|---------|-------------|
|
||||
| `variant` | `card \| table \| dashboard \| toolbar \| editor \| wizard` | `card` | Bestimmt CSS-Verhalten (Flex, Padding, Border) |
|
||||
| `title` | `string \| ReactNode` | - | Header-Titel (wenn gesetzt, wird Header gerendert) |
|
||||
| `subtitle` | `string \| ReactNode` | - | Untertitel im Header |
|
||||
| `actions` | `ReactNode` | - | Action-Buttons im Header |
|
||||
| `collapsible` | `boolean` | `false` | Collapse/Expand-Toggle im Header |
|
||||
| `defaultCollapsed` | `boolean` | `false` | Initial-Zustand |
|
||||
| `collapseKey` | `string` | - | localStorage-Key fuer Persistenz (`panel-collapse:{key}`) |
|
||||
|
||||
### Varianten-Verhalten
|
||||
|
||||
| Variant | flex | Padding | Border | Typischer Inhalt |
|
||||
|---------|------|---------|--------|-----------------|
|
||||
| `card` | - | 14px | Standard-Card | Info-Sektionen, Settings, Formulare |
|
||||
| `table` | flex:1, min-height:0 | 0 | Standard-Card | FormGeneratorTable |
|
||||
| `dashboard` | - | 14px | Standard-Card | KPI-Grid, Stats-Cards |
|
||||
| `toolbar` | - | 8px 14px | kein Radius | Filter-Bar, Actions, kompakt |
|
||||
| `editor` | flex:1, min-height:0 | 0 | Standard-Card | Code-Editor, Flow-Editor, Chat |
|
||||
| `wizard` | - | 20px | Standard-Card | Wizard-Schritte |
|
||||
|
||||
### Generische Aenderungen
|
||||
|
||||
CSS-Aenderungen an `[data-variant="table"]` in `Panel.module.css` wirken auf ALLE Tabellen-Regionen im System. Beispiel:
|
||||
|
||||
```css
|
||||
/* Panel.module.css */
|
||||
.panel[data-variant="table"] .body {
|
||||
min-height: 300px; /* wirkt systemweit fuer alle Tabellen */
|
||||
}
|
||||
```
|
||||
|
||||
### Beispiel: Collapsible Dashboard
|
||||
|
||||
```tsx
|
||||
<Panel variant="dashboard" title="Uebersicht" collapsible collapseKey="dashboard-overview">
|
||||
<div className={styles.kpiGrid}>
|
||||
<StatCard label="Workflows" value={7} />
|
||||
<StatCard label="Aktiv" value={5} />
|
||||
</div>
|
||||
</Panel>
|
||||
```
|
||||
|
||||
## LayoutTabs
|
||||
|
||||
Einziges Tab-System. Ersetzt `UiComponents/Tabs` und alle manuellen Tab-Button-Implementierungen.
|
||||
|
||||
### Props
|
||||
|
||||
| Prop | Typ | Default | Beschreibung |
|
||||
|------|-----|---------|-------------|
|
||||
| `items` | `LayoutTabItem[]` | - | Tab-Definitionen |
|
||||
| `urlParam` | `string` | - (kein Default) | URL-Search-Parameter fuer aktiven Tab |
|
||||
| `defaultTab` | `string` | erstes Item | Fallback wenn URL-Param fehlt |
|
||||
| `preserveSearchParams` | `boolean` | `true` | Andere URL-Params beim Tab-Wechsel erhalten |
|
||||
| `aliasMap` | `Record<string, string>` | - | URL-Wert -> Tab-ID Mapping |
|
||||
| `syncUrl` | `boolean` | `!!urlParam` | Tab-Wechsel schreibt in URL (default: an, wenn `urlParam` gesetzt) |
|
||||
| `lazy` | `boolean` | `false` | Wenn `true`: besuchte Tabs bleiben gemountet (`display:none`), State bleibt erhalten. Wenn `false`: nur aktiver Tab gemountet, Wechsel remountet (State-Verlust). Fuer Tab-Sets mit Formularen/Streams `lazy` setzen. |
|
||||
| `collapsible` | `boolean` | `false` | Tab-Bar einklappbar |
|
||||
|
||||
### LayoutTabItem
|
||||
|
||||
```typescript
|
||||
interface LayoutTabItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon?: ReactNode;
|
||||
group?: string; // Gruppierung (Kategorie-Titel)
|
||||
disabled?: boolean;
|
||||
render: () => ReactNode;
|
||||
}
|
||||
```
|
||||
|
||||
### Beispiel: Gruppierte Tabs
|
||||
|
||||
```tsx
|
||||
<LayoutTabs
|
||||
urlParam="tab"
|
||||
defaultTab="workflows"
|
||||
items={[
|
||||
{ id: 'workflows', label: 'Workflows', group: 'Ausfuehren', render: () => <WorkflowsTab /> },
|
||||
{ id: 'runs', label: 'Durchlaeufe', group: 'Ausfuehren', render: () => <RunsTab /> },
|
||||
{ id: 'editor', label: 'Editor', group: 'Erstellen', render: () => <EditorTab /> },
|
||||
{ id: 'templates', label: 'Vorlagen', group: 'Erstellen', render: () => <TemplatesTab /> },
|
||||
]}
|
||||
/>
|
||||
```
|
||||
|
||||
## ViewStack
|
||||
|
||||
Master-Detail-Navigation. Modi `list | catalog | detail` via URL-Parameter.
|
||||
|
||||
### Props
|
||||
|
||||
| Prop | Typ | Default | Beschreibung |
|
||||
|------|-----|---------|-------------|
|
||||
| `viewParam` | `string` | `'view'` | URL-Parameter fuer aktive View |
|
||||
| `entityParam` | `string` | - | URL-Parameter fuer Entity-ID (z.B. `runId`) |
|
||||
| `defaultView` | `ViewMode` | `'list'` | Fallback-View |
|
||||
|
||||
### View-Modi
|
||||
|
||||
| Modus | URL-Beispiel | Verhalten |
|
||||
|-------|-------------|-----------|
|
||||
| `list` | `/workflows` | Listenansicht (FormGeneratorTable) |
|
||||
| `catalog` | `/workflows?view=catalog` | Katalog/Grid-Ansicht |
|
||||
| `detail` | `/workflows?view=detail&runId=abc` | Detail-Ansicht mit Entity |
|
||||
|
||||
## Seiten-Aufbau-Muster
|
||||
|
||||
### Muster 1: Einfache Tabellen-Seite
|
||||
|
||||
```
|
||||
StackLayout (variant="table")
|
||||
└── Body
|
||||
├── Panel (variant="toolbar"): Header-Actions, Filter
|
||||
└── Panel (variant="table", collapsible): FormGeneratorTable
|
||||
```
|
||||
|
||||
Beispiele: AdminUsersPage, AdminMandatesPage, PromptsPage, ConnectionsPage
|
||||
|
||||
### Muster 2: Dashboard-Seite
|
||||
|
||||
```
|
||||
StackLayout (variant="dashboard")
|
||||
└── Body
|
||||
├── Panel (variant="dashboard"): KPI-Grid
|
||||
├── Panel (variant="card", collapsible): Themen/Module
|
||||
└── Panel (variant="card", collapsible): Details/Info
|
||||
```
|
||||
|
||||
Beispiele: TrusteeDashboardView, CommcoachDashboardView, TeamsbotDashboardView
|
||||
|
||||
### Muster 3: Seite mit Tabs
|
||||
|
||||
```
|
||||
StackLayout (variant="table")
|
||||
└── Body
|
||||
├── Panel (variant="toolbar"): Kontext-Filter (optional)
|
||||
└── LayoutTabs (urlParam="tab")
|
||||
├── Tab "uebersicht": Panel (variant="dashboard") + Panel (variant="table")
|
||||
└── Tab "settings": Panel (variant="card")
|
||||
```
|
||||
|
||||
Beispiele: WorkflowAutomationHubPage, Settings, ComplianceAuditPage
|
||||
|
||||
### Muster 4: Wizard-Seite
|
||||
|
||||
```
|
||||
StackLayout (variant="form")
|
||||
└── Body
|
||||
├── Panel (variant="toolbar"): Step-Indicator + Navigation
|
||||
└── Panel (variant="wizard"): Step-Inhalt
|
||||
```
|
||||
|
||||
Beispiele: AdminMandateWizardPage, AdminInvitationWizardPage
|
||||
|
||||
### Muster 5: Editor/Chat-Seite
|
||||
|
||||
```
|
||||
StackLayout (variant="scroll")
|
||||
└── Body
|
||||
└── Panel (variant="editor"): Editor/Chat (flex:1, volle Hoehe)
|
||||
```
|
||||
|
||||
Beispiele: WorkflowEditorPage, ChatStream
|
||||
|
||||
### Muster 6: Split-Layout (Phase 6b PanelLayout)
|
||||
|
||||
```
|
||||
PanelLayout (config-getriebener Split-Tree)
|
||||
├── Panel links: Sidebar (collapsible, resizable)
|
||||
├── Panel mitte: Hauptinhalt
|
||||
└── Panel rechts: Detail/Preview (collapsible, resizable)
|
||||
```
|
||||
|
||||
Beispiele: WorkspacePage, FilesPage, CommcoachDossierView, RedmineBrowserView
|
||||
|
||||
## Migrations-Checkliste
|
||||
|
||||
Bei JEDER Seiten-Migration abarbeiten (Lessons aus Phase 4):
|
||||
|
||||
### 1. Daten & API
|
||||
- Mandantenfilter: "Alle" = kein `mandateId`-Param, Backend filtert per User-Mandatsliste
|
||||
- Daten-Reload bei Kontextwechsel: Dependencies muessen `selectedMandateId` enthalten
|
||||
- Metriken/Dashboard konsistent mit Tabelle: Gleicher Scope
|
||||
|
||||
### 2. FK-Label-Resolution
|
||||
- displayField-Konvention: `{fieldName}Label` (z.B. `workflowId` -> `workflowIdLabel`)
|
||||
- `enrichRowsWithFkLabels` in ALLEN Pfaden (Standard + filterValues)
|
||||
- Cross-Mandate FK-Lookup: `getRecord()` statt mandate-scoped Methoden
|
||||
|
||||
### 3. FormGeneratorTable Integration
|
||||
- `hookData.refetch` als einziger Datenpfad
|
||||
- Keine redundanten Filter-Buttons (FormGeneratorTable hat eingebaute Filter)
|
||||
- Kein RBAC im UI
|
||||
|
||||
### 4. Backend RBAC
|
||||
- Kein `isPlatformAdmin`-Bypass fuer Lesezugriffe
|
||||
- Fail-closed: Fehlender Filter = leeres Ergebnis (`__impossible__`-Sentinel)
|
||||
- `mandateId`-Validierung gegen `userMandateIds`
|
||||
|
||||
### 5. Layout & UI
|
||||
- StackLayout + Panel verwenden, URL als Source-of-Truth
|
||||
- Panel fuer collapsible Bloecke
|
||||
- scrollMode-Integration: min-height im document-Mode
|
||||
|
||||
### 6. Keep-Alive (nur fuer registrierte Seiten)
|
||||
- Pruefen ob Seite in `config/keepAliveRoutes.tsx` registriert ist
|
||||
- Bei Wiedereinblenden Re-Measure/Re-Clamp ausloesen (Hoehe war `display:none` -> 0)
|
||||
- `matchLocation`-Bedingung bei Tab-basierten Keep-Alive-Routes erhalten (z.B. `?tab=editor`)
|
||||
- `scopeKey` (Mandant/Instanz) als React-`key` beibehalten — Scope-Wechsel = Neu-Mount
|
||||
- Resize-/SSE-Listener-Cleanup darf persistenten State nicht zerstoeren
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
| Anti-Pattern | Stattdessen |
|
||||
|-------------|-------------|
|
||||
| `styles.adminPage` / `adminPageFill` | `StackLayout` mit passender Variante |
|
||||
| `styles.tableContainer` | `Panel variant="table"` |
|
||||
| `styles.pageHeader` mit inline Actions | `Panel variant="toolbar"` oder `StackLayout.Header` |
|
||||
| Manuelle Tab-Buttons (`onClick`, `activeTab` State) | `LayoutTabs` mit `urlParam` |
|
||||
| `UiComponents/Tabs` | `LayoutTabs` |
|
||||
| `useState` fuer aktiven Tab | URL via `urlParam` |
|
||||
| `isPlatformAdmin` Bypass im Backend | Mandate-scoped Filter mit fail-closed |
|
||||
| `modalOverlay` CSS per Seite dupliziert | (siehe separater Modal-Konsolidierungsplan) |
|
||||
|
||||
## Dateien
|
||||
|
||||
| Datei | Zweck |
|
||||
|-------|-------|
|
||||
| `components/Layout/StackLayout.tsx` + `.module.css` | Seiten-Container |
|
||||
| `components/Layout/Panel.tsx` + `.module.css` | Typisierte Region |
|
||||
| `components/Layout/LayoutTabs.tsx` + `.module.css` | Tab-System |
|
||||
| `components/Layout/ViewStack.tsx` + `.module.css` | Master-Detail |
|
||||
| `components/Layout/types.ts` | Shared TypeScript-Typen |
|
||||
| `hooks/useScrollMode.ts` | Scroll-Modus-Erkennung |
|
||||
| `config/keepAliveRoutes.tsx` | Keep-Alive-Registrierung (persistente Seiten) |
|
||||
| `layouts/MainLayout.tsx` + `.module.css` | App-Shell (Sidebar + Content) |
|
||||
| `layouts/FeatureLayout.tsx` + `.module.css` | Feature-Chrome (Breadcrumb, Kontext) |
|
||||
| `pages/FeatureView.tsx` + `.module.css` | View-Router fuer Feature-Instanzen |
|
||||
438
c-work/1-plan/2026-06-layout-foundation.md
Normal file
438
c-work/1-plan/2026-06-layout-foundation.md
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
<!-- status: build -->
|
||||
<!-- started: 2026-06-10 -->
|
||||
<!-- component: ui-nyla -->
|
||||
|
||||
# Layout Foundation — Gesamtplan
|
||||
|
||||
## Beschreibung und Kontext
|
||||
|
||||
Auf kleinen Viewports/Mobile fuellt der statische Header die Seite komplett aus. Die `FormGeneratorTable` wird unbedienbar. Ursache: die gesamte Ahnenkette ist `overflow:hidden` mit `flex-shrink:0` fuer Chrome-Bereiche.
|
||||
|
||||
Strukturproblem: Manuelles Layout-Pattern (`adminPage`/`adminPageFill`/`pageHeader`/`tableContainer`), 15+ Ad-hoc-Tab-Implementierungen, Workspace komplett Inline mit lokalem `_useResizable`, keine Persistenz.
|
||||
|
||||
Strategisches Ziel: Einheitliche Layout-Architektur fuer alle Seiten (Feature-Views, Admin, Basedata, Systemkomponenten). Die Solution-Schicht L3/L4 wird als **separater** Plan umgesetzt.
|
||||
|
||||
Referenz-Plan: `pagelayout_component_system_fd9fde3a.plan.md` (v3)
|
||||
|
||||
**Region-Zuordnung pro Seite**: [`2026-06-layout-regions.md`](2026-06-layout-regions.md) — definiert fuer jede Seite explizit, welche Panel-Varianten und LayoutTabs eingesetzt werden.
|
||||
|
||||
## Fokus und kritische Details
|
||||
|
||||
- **Scroll-Mode** ist das hoechste Risiko — Phase 0 war gating (erledigt)
|
||||
- Doppeltes Padding (featureContent + viewContent je 1.5rem) frisst Platz (erledigt)
|
||||
- FormGeneratorTable braucht bounded height fuer internen Scroll (Desktop) aber natural height (Mobile)
|
||||
- Master->Detail auf derselben Seite: Liste UND Detail-Formular muessen bedienbar sein
|
||||
- Keep-Alive-Routes (Workspace) sind `position:absolute` — Phase 6 (eigener Scope)
|
||||
- **Migrations-Checkliste** (Abschnitt unten) bei JEDER Seite abarbeiten — Lessons aus Phase 4
|
||||
|
||||
## Ziel und Nicht-Ziele
|
||||
|
||||
- Ziel: Alle Seiten auf StackLayout/LayoutTabs/Panel migrieren
|
||||
- Ziel: UiComponents/Tabs und Ad-hoc-Tab-Implementierungen eliminieren
|
||||
- Ziel: Admin.module.css Layout-Klassen eliminieren (Button/Form/Modal bleiben)
|
||||
- Explizit NICHT in diesem Plan: SolutionsView (eigener Plan als Systemkomponente)
|
||||
|
||||
## Betroffene Module
|
||||
|
||||
- Frontend: Layout-Kette (MainLayout, FeatureLayout, FeatureView), Admin.module.css, FormGeneratorTable
|
||||
- Primitives: `ui-nyla/src/components/Layout/*` (bereits erstellt)
|
||||
- Hooks: `ui-nyla/src/hooks/useScrollMode.ts` (bereits erstellt)
|
||||
- DB-Migration: nein
|
||||
- Andere Komponenten: nein
|
||||
|
||||
## Entscheidungen
|
||||
|
||||
| Datum | Entscheidung | Begruendung |
|
||||
|-------|-------------|------------|
|
||||
| 2026-06-10 | scrollMode via `data-scroll-mode` auf `<html>` + CSS `:global()` | CSS-Module-kompatibel, keine Prop-Drilling, ein Hook steuert alles |
|
||||
| 2026-06-10 | Breakpoints: `max-width:1024px` OR `max-height:500px` -> document mode | Matching bestehender Mobile-Breakpoint + extrem kurze Desktop-Fenster |
|
||||
| 2026-06-10 | SolutionsView als Systemkomponente, nicht Feature-View | Solutions ist mandantuebergreifend wie WorkflowAutomation |
|
||||
| 2026-06-10 | SolutionsView-Stub entfernen, Neuaufbau in eigenem Plan | Kein Placeholder-Code ohne Backend |
|
||||
| 2026-06-10 | composer-2.5-fast fuer repetitive Seiten-Migrationen | Schnell und guenstig fuer Pattern-Anwendung auf viele Dateien |
|
||||
| 2026-06-10 | Desktop-Sidebar: collapsible + resizable | Mehr Platz fuer Content, User-Kontrolle ueber Sidebar-Breite |
|
||||
| 2026-06-10 | Panel bekommt `variant`-Prop (card/table/dashboard/toolbar/editor/wizard) | Generische Styles pro Regionstyp, systemweite Aenderungen an einem Ort |
|
||||
| 2026-06-10 | Generische Infra (5-pre) + PanelLayout (6b) VOR Massenmigration | Subagenten koennen Checkliste sonst nicht erfuellen; verhindert inkonsistente Layouts |
|
||||
| 2026-06-10 | ViewStack verwaltet nur eigene URL-Params (kein `tab`-Delete) | Behebt Back-Bug bei in LayoutTabs verschachtelten ViewStacks |
|
||||
| 2026-06-10 | Kontextfilter via URL (`?context=`) statt useState | URL-als-Source-of-Truth konsequent; teilbare Links |
|
||||
| 2026-06-10 | Tote/nicht-geroutete Seiten -> Phase 7, nicht Migration | Keine Arbeit an Dead-Code; erst Routing klaeren |
|
||||
|
||||
## Scroll-Vertrag
|
||||
|
||||
### Modi
|
||||
|
||||
| Modus | Bedingung | Verhalten |
|
||||
|-------|-----------|-----------|
|
||||
| `bounded` | viewport > 1024px Breite UND > 500px Hoehe | `overflow:hidden`-Kette intakt, Tabelle scrollt intern, Header bleibt sichtbar |
|
||||
| `document` | viewport <= 1024px ODER <= 500px Hoehe | `overflow:visible`-Kette, Seite scrollt als Dokument, Header scrollt weg, Tabelle waechst natuerlich |
|
||||
|
||||
### CSS-Mechanismus
|
||||
|
||||
Hook `useScrollMode()` setzt `document.documentElement.dataset.scrollMode`.
|
||||
CSS-Module nutzen `:global(html[data-scroll-mode="document"])` als Selektor-Prefix.
|
||||
|
||||
## Phasen-Uebersicht
|
||||
|
||||
| Phase | Inhalt | Status |
|
||||
|-------|--------|--------|
|
||||
| 0 | Scroll-Mode-Spike | erledigt |
|
||||
| 1 | Feature-Chrome-Budget | erledigt |
|
||||
| 2 | Primitive (Panel, LayoutTabs, ViewStack, StackLayout, Persistence) | erledigt |
|
||||
| 3 | ~~SolutionsView MVP~~ | entfernt (falsch als Feature-View, eigener Plan) |
|
||||
| 4a | TrusteeDataTablesView -> StackLayout + LayoutTabs | erledigt |
|
||||
| 4b | WorkflowAutomationHubPage -> StackLayout + LayoutTabs + ViewStack | erledigt |
|
||||
| 4c | **GATE** Korrekturen: RunsTab/WorkflowsTab tableContainer, SolutionsView loeschen, Hub-Filter in URL (erledigt), ViewStack tab-delete-Fix (erledigt) | offen |
|
||||
| 4d | Panel um `variant`-Prop erweitern (card, table, dashboard, toolbar, editor, wizard) | erledigt |
|
||||
| 5a | Doku-Sync: layout.md (erstellt, Defaults gefixt), formgenerator.md, TOPICS.md (erstellt), Region-Specs vervollstaendigen | teilw. erledigt |
|
||||
| **5-pre** | **GATE** Generische Infrastruktur bauen (L2/L7/L8/L10/L11 + Keep-Alive-Remeasure) — MUSS vor 5b stehen | offen |
|
||||
| 6b | **vorgezogen vor 5d/5e/5j**: PanelLayout-MVP (config-getriebener Split-Tree) ODER Interim-Split-Pattern dokumentieren | offen |
|
||||
| 5b | Trustee-Views migrieren (8 geroutete Seiten; eingebettete separat in 5i) | offen |
|
||||
| 5c | Admin-Seiten migrieren (21 Seiten) | offen |
|
||||
| 5d | Basedata-Seiten migrieren (3 Seiten; FilesPage Split -> 6b) | offen |
|
||||
| 5e | Feature-Views migrieren: Commcoach (5 geroutet), Teamsbot (5), RealEstate (2 geroutet + pek-Subkomp.), Redmine (4), Neutralization (1), Chatworkflow (3) | offen |
|
||||
| 5f | Billing-Seiten migrieren (nur geroutete; siehe Dead-Code-Verifikation) | offen |
|
||||
| 5g | Top-Level-Seiten migrieren (8 Seiten) | offen |
|
||||
| 5g2 | Auth-Seiten pruefen (5 Seiten, eigenes Layout) | offen |
|
||||
| 5h | WorkflowAutomation: Hub-Chrome + WorkflowsTab/RunsTab + Views + Sub-Tabs | offen |
|
||||
| 5i | Trustee Sub-Komponenten (TrusteeDataTab, eingebettete Positions/Documents-Views als Panel-Body-only) | offen |
|
||||
| 5j | Workspace-Views migrieren (9 Seiten; Split -> 6b) | offen |
|
||||
| 6a | Navigation: Desktop-Sidebar collapse + resize | offen |
|
||||
| 7 | Cleanup: grep-gated Loeschen alter Layout-Klassen, UiComponents/Tabs, **tote Seiten (siehe Dead-Code-Verifikation)** | offen |
|
||||
|
||||
## Umsetzungs-Checkliste
|
||||
|
||||
### Phase 4c — Korrekturen (sofort)
|
||||
|
||||
- [ ] SolutionsView aus FeatureView.tsx deregistrieren (Import + Map-Eintrag `trustee.solutions`)
|
||||
- [ ] `src/pages/views/solutions/` komplett loeschen (SolutionsView.tsx + .module.css)
|
||||
- [ ] RunsTab: `styles.tableContainer` entfernen
|
||||
- [ ] WorkflowsTab: `styles.tableContainer` entfernen
|
||||
- [x] Hub-Kontextfilter `selectedMandateId` von `useState` auf URL (`?context=`) — erledigt
|
||||
- [x] ViewStack: pauschales `next.delete('tab')` entfernt (Back-Bug bei nested Tabs) — erledigt
|
||||
- [ ] TypeScript-Build pruefen
|
||||
|
||||
### Phase 5a — Dokumentation
|
||||
|
||||
- [x] `wiki/b-reference/ui-nyla/layout.md` erstellt (Scroll-Modi, Layout-Kette, Primitive, Migrations-Checkliste); Defaults an Code angeglichen
|
||||
- [ ] `wiki/b-reference/ui-nyla/formgenerator.md` aktualisieren (Page Layout Chain, hookData.refetch, FK-Labels)
|
||||
- [x] `wiki/TOPICS.md` aktualisiert
|
||||
- [ ] CHANGELOG-Eintraege (laufend)
|
||||
- [ ] Region-Specs vervollstaendigen (StackLayout-Variant pro tabbed Seite explizit)
|
||||
|
||||
### Phase 5-pre — Generische Infrastruktur (GATE, vor allen Massenmigrationen)
|
||||
|
||||
Diese Bausteine MUESSEN existieren, bevor Subagenten die Migrations-Checkliste erfuellen koennen. Sonst entscheidet jeder Subagent anders bzw. die Checkliste ist nicht umsetzbar.
|
||||
|
||||
- [ ] **`useDocumentTitle`-Hook** (L11): setzt `${appName} - ${seitentitel}`. MUSS sichtbarkeits-/aktiv-route-gated sein (nur setzen wenn eigene Route aktiv) — sonst ueberschreibt eine versteckte Keep-Alive-Seite mit SSE/State-Updates den Titel der sichtbaren Seite. Hardcoded Auth-Titel (Login/Register/Reset) auf Hook + `t()` umstellen.
|
||||
- [ ] **Scroll-Restoration** (L2): generischer Mechanismus (Hook/Layout) — Position merken, bei fehlendem Ziel auf Top. Fuer document- UND bounded-Scroll.
|
||||
- [ ] **ViewStack URL-Validierung + Toast** (L8): bei ungueltiger `view`/`entity`-Kombi Toast + sauberer Fallback (statt stillem Resolve).
|
||||
- [ ] **Detail-Breadcrumb** (L7, niedrige Prio): generisch im ViewStack/Header-Slot (NICHT FeatureLayout). ViewStack hat bereits `detailHeader`; nur ergaenzen falls Crumb-Kette gewuenscht.
|
||||
- [ ] **Filter/Search-Persistenz-Contract** (L10): FormGeneratorTable-Filter in localStorage (scoped key).
|
||||
- [ ] **Keep-Alive Re-Measure-Hook**: generischer `useVisibilityRemeasure` statt ad-hoc in FormGeneratorTable (Hoehe nach `display:none` -> 0).
|
||||
- [ ] **Referenz-Migration als Gold-Standard fixieren — nur AEUSSERE Struktur** (StackLayout-Variant, LayoutTabs, ViewStack, Kontext-via-URL): TrusteeDataTablesView + WorkflowAutomationHubPage. Die Panel-isierung der Tab-Bodies (RunsTab/WorkflowsTab in 4c/5h, TrusteeDataTab in 5i) ist NICHT Teil des Freeze, da sie erst spaeter migriert werden.
|
||||
|
||||
### Phase 5b — Trustee-Views (geroutet; Subagent composer-2.5-fast)
|
||||
|
||||
Nur via FeatureView-Registry geroutete Views. Eingebettete (Positions/Documents) siehe 5i. Tote siehe Dead-Code-Verifikation.
|
||||
|
||||
- [ ] TrusteeAbschlussView.tsx — inline Tab-Buttons -> LayoutTabs
|
||||
- [ ] TrusteeAccountingSettingsView.tsx — inline Tab-Buttons -> LayoutTabs
|
||||
- [ ] TrusteeAnalyseView.tsx — inline Tab-Buttons -> LayoutTabs
|
||||
- [ ] TrusteeDashboardView.tsx — dashboardView CSS -> StackLayout
|
||||
- [ ] TrusteeImportProcessView.tsx — inline Tab-Buttons -> LayoutTabs
|
||||
- [ ] TrusteeInstanceRolesView.tsx — viewContainer CSS -> StackLayout
|
||||
- [ ] TrusteeExpenseImportView.tsx — inline Layout -> StackLayout (Routing pruefen: nicht in Registry)
|
||||
- [ ] TrusteeScanUploadView.tsx — inline Layout -> StackLayout (Routing pruefen: nicht in Registry)
|
||||
|
||||
### Phase 5c — Admin-Seiten (21 Seiten, Subagent composer-2.5-fast)
|
||||
|
||||
- [ ] AdminUsersPage.tsx
|
||||
- [ ] AdminUserMandatesPage.tsx
|
||||
- [ ] AdminUserAccessOverviewPage.tsx — manuelle Tab-Buttons -> LayoutTabs
|
||||
- [ ] AdminMandatesPage.tsx
|
||||
- [ ] AdminMandateRolesPage.tsx
|
||||
- [ ] AdminMandateRolePermissionsPage.tsx
|
||||
- [ ] AdminLogsPage.tsx
|
||||
- [ ] AdminLanguagesPage.tsx
|
||||
- [ ] AdminInvitationsPage.tsx
|
||||
- [ ] AdminFeatureRolesPage.tsx
|
||||
- [ ] AdminFeatureInstanceUsersPage.tsx
|
||||
- [ ] AdminFeatureAccessPage.tsx
|
||||
- [ ] AdminDemoConfigPage.tsx
|
||||
- [ ] AdminDatabaseHealthPage.tsx — UiComponents/Tabs -> LayoutTabs
|
||||
- [ ] AccessManagementHub.tsx
|
||||
- [ ] PermissionMatrix.tsx
|
||||
- [ ] InstanceHierarchyView.tsx
|
||||
- [ ] InstanceDetailModal.tsx
|
||||
- [ ] wizards/AdminMandateWizardPage.tsx
|
||||
- [ ] wizards/AdminInvitationWizardPage.tsx
|
||||
- [ ] wizards/FeatureInstanceWizard.tsx
|
||||
|
||||
### Phase 5d — Basedata-Seiten (3 Seiten, Subagent composer-2.5-fast)
|
||||
|
||||
- [ ] ConnectionsPage.tsx — adminPage/adminPageFill -> StackLayout
|
||||
- [ ] FilesPage.tsx — adminPage/adminPageFill -> StackLayout
|
||||
- [ ] PromptsPage.tsx — adminPage/adminPageFill -> StackLayout
|
||||
|
||||
### Phase 5e — Weitere Feature-Views (Subagent composer-2.5-fast)
|
||||
|
||||
Nur geroutete Views (FeatureView-Registry). Tote siehe Dead-Code-Verifikation.
|
||||
|
||||
Commcoach (5 geroutet):
|
||||
- [ ] CommcoachAssistantView.tsx
|
||||
- [ ] CommcoachDashboardView.tsx
|
||||
- [ ] CommcoachModulesView.tsx
|
||||
- [ ] CommcoachSessionView.tsx ([KEEP-ALIVE]; Split -> 6b)
|
||||
- [ ] CommcoachSettingsView.tsx — manuelle Tabs -> LayoutTabs
|
||||
|
||||
Teamsbot (5):
|
||||
- [ ] TeamsbotAssistantView.tsx
|
||||
- [ ] TeamsbotDashboardView.tsx
|
||||
- [ ] TeamsbotModulesView.tsx
|
||||
- [ ] TeamsbotSessionView.tsx ([KEEP-ALIVE NEU]; Split -> 6b)
|
||||
- [ ] TeamsbotSettingsView.tsx — manuelle Tabs -> LayoutTabs
|
||||
|
||||
RealEstate (2 geroutet + Subkomponenten):
|
||||
- [ ] RealEstatePekView.tsx (Registry: `dashboard`)
|
||||
- [ ] RealEstateInstanceRolesPlaceholder.tsx (Registry: `instance-roles`)
|
||||
- [ ] pek/PekMapView.tsx — Subkomponente von PekView
|
||||
- [ ] pek/PekLocationInput.tsx — Subkomponente von PekView
|
||||
|
||||
Chatworkflow (3 geroutet, aber reine PlaceholderViews in FeatureView):
|
||||
- [ ] NICHT migrieren solange Platzhalter — entweder echte Implementierung abwarten oder Phase 7. In Dead-Code-Verifikation aufgenommen.
|
||||
|
||||
Redmine (4):
|
||||
- [ ] RedmineBrowserView.tsx ([KEEP-ALIVE NEU]; Split -> 6b)
|
||||
- [ ] RedmineSettingsView.tsx
|
||||
- [ ] RedmineStatsView.tsx
|
||||
- [ ] RedmineTicketEditor.tsx — Subkomponente von BrowserView
|
||||
|
||||
Neutralization (1):
|
||||
- [ ] NeutralizationView.tsx — UiComponents/Tabs -> LayoutTabs
|
||||
|
||||
### Phase 5f — Billing-Seiten (nur geroutete, Subagent composer-2.5-fast)
|
||||
|
||||
Geroutet in App.tsx: BillingDataView, BillingAdmin, BillingMandateView, AdminSubscriptionsPage. `BillingDashboard`/`BillingTransactions`/`BillingUserView` sind tot (siehe Dead-Code-Verifikation) -> Phase 7, NICHT migrieren.
|
||||
|
||||
- [ ] BillingDataView.tsx
|
||||
- [ ] BillingAdmin.tsx
|
||||
- [ ] BillingMandateView.tsx
|
||||
- [ ] AdminSubscriptionsPage.tsx
|
||||
- [ ] BillingNav.tsx — Subkomponente (von BillingMandateView genutzt), KEIN eigenes StackLayout
|
||||
- [ ] SubscriptionTab.tsx — Subkomponente von AdminSubscriptionsPage
|
||||
- [ ] EnterpriseDialog.tsx — Modal, nur falls vom Modal-Plan beruehrt
|
||||
|
||||
### Phase 5g — Top-Level-Seiten (8 Seiten)
|
||||
|
||||
- [ ] Dashboard.tsx (export DashboardPage)
|
||||
- [ ] Settings.tsx (export SettingsPage)
|
||||
- [ ] Store.tsx (export StorePage)
|
||||
- [ ] IntegrationsOverviewPage.tsx
|
||||
- [ ] ComplianceAuditPage.tsx
|
||||
- [ ] RagInventoryPage.tsx
|
||||
- [ ] GDPR.tsx (export GDPRPage)
|
||||
- [ ] FeatureView.tsx — View-Router/Container, CSS pruefen
|
||||
|
||||
### Phase 5g2 — Auth-Seiten (5 Seiten, eigenes Layout ohne MainLayout)
|
||||
|
||||
- [ ] Login.tsx — Standalone, kein Feature-Chrome
|
||||
- [ ] Register.tsx — Standalone, kein Feature-Chrome
|
||||
- [ ] PasswordResetRequest.tsx — Standalone, kein Feature-Chrome
|
||||
- [ ] Reset.tsx — Standalone, kein Feature-Chrome
|
||||
- [ ] InvitePage.tsx — Standalone, kein Feature-Chrome
|
||||
|
||||
### Phase 5h — WorkflowAutomation Views + Sub-Tabs (6 Seiten)
|
||||
|
||||
- [ ] views/workflowAutomation/WorkflowTemplatesPage.tsx — adminPage -> StackLayout
|
||||
- [ ] views/workflowAutomation/WorkflowEditorPage.tsx — inline flex -> StackLayout
|
||||
- [ ] tabs/TemplatesTab.tsx
|
||||
- [ ] tabs/EditorTab.tsx
|
||||
- [ ] tabs/TasksTab.tsx — Admin.module.css -> StackLayout
|
||||
- [ ] tabs/RunDetailTab.tsx — Admin.module.css -> StackLayout
|
||||
|
||||
### Phase 5i — Trustee Sub-Komponenten
|
||||
|
||||
- [ ] dataTables/TrusteeDataTab.tsx — eingebettet in TrusteeDataTablesView
|
||||
- [ ] components/index.ts — leer, ggf. loeschen in Phase 7
|
||||
|
||||
### Phase 5j — Workspace-Views (9 Seiten)
|
||||
|
||||
- [ ] WorkspacePage.tsx — Custom 3-Column Split -> StackLayout + PanelLayout-Vorbereitung
|
||||
- [ ] WorkspaceEditorPage.tsx — inline flex -> StackLayout
|
||||
- [ ] WorkspaceSettingsPage.tsx — inline flex -> StackLayout
|
||||
- [ ] WorkspaceGeneralSettings.tsx — Settings-Layout
|
||||
- [ ] WorkspaceInput.tsx — Chat-Input-Komponente
|
||||
- [ ] ChatStream.tsx — Chat-Stream-Panel
|
||||
- [ ] FilePreview.tsx — Datei-Vorschau-Panel
|
||||
- [ ] NeutralizationPanel.tsx — Neutralisierungs-Panel
|
||||
- [ ] ToolActivityLog.tsx — Tool-Activity-Log-Panel
|
||||
|
||||
### Phase 6a — Navigation: Desktop-Sidebar collapse + resize
|
||||
|
||||
Aktueller Stand: Sidebar ist fix 280px, nicht ausblendbar (Desktop), nicht breitenverstellbar.
|
||||
Mobile (<=1024px) hat bereits Overlay-Hamburger-Menu — das bleibt.
|
||||
|
||||
- [ ] **Collapse-Toggle**: Button im Sidebar-Header oder am Rand, klappt Sidebar auf Icon-Only-Breite (~60px)
|
||||
- [ ] **Resize-Handle**: Drag-Handle am rechten Rand der Sidebar, Breite zwischen min (~180px) und max (~400px) einstellbar
|
||||
- [ ] **Persistenz**: Collapse-State und Breite in localStorage speichern (`sidebar-collapsed`, `sidebar-width`)
|
||||
- [ ] **Keyboard-Shortcut**: z.B. `Ctrl+B` zum Toggling (wie VS Code)
|
||||
- [ ] **CSS-Transition**: Smooth animation fuer Collapse (200-300ms ease)
|
||||
- [ ] **Content-Bereich reagiert**: `flex: 1` auf Content bleibt, passt sich automatisch an
|
||||
- [ ] **Logo-Bereich**: Im collapsed State nur Icon, kein Text
|
||||
- [ ] **Navigation-Items**: Im collapsed State nur Icons, Tooltip bei Hover
|
||||
- [ ] **UserSection**: Im collapsed State kompakt (nur Avatar)
|
||||
- [ ] Betrifft: `MainLayout.tsx`, `MainLayout.module.css`, `MandateNavigation.tsx`, `UserSection.tsx`
|
||||
|
||||
### Phase 7 — Cleanup (nach Phase 5)
|
||||
|
||||
- [ ] grep-Pruefung: Null-Nutzung von `adminPage`/`adminPageFill`/`pageHeader`/`tableContainer` Layout-Klassen (inkl. `adminPage` ohne Suffix)
|
||||
- [ ] Tote Seiten aus Dead-Code-Verifikation loeschen oder integrieren
|
||||
- [ ] Admin.module.css: Layout-Klassen entfernen (Button/Form/Modal bleiben)
|
||||
- [ ] UiComponents/Tabs: Null-Nutzung pruefen, dann loeschen
|
||||
- [ ] Finale TypeScript-Build-Pruefung
|
||||
- [ ] Finale Lint-Pruefung aller geaenderter Dateien
|
||||
- [ ] Aenderungs-Zusammenfassung erstellen
|
||||
|
||||
## Dead-Code-Verifikation (vor Migration klaeren, NICHT migrieren)
|
||||
|
||||
Diese Dateien sind weder via FeatureView-Registry geroutet noch irgendwo importiert (Stand 2026-06-10). Sie gehoeren NICHT in die Migrations-Batches, sondern in Phase 7 Cleanup — entweder loeschen oder bewusst (re-)integrieren.
|
||||
|
||||
| Datei | Befund | Aktion |
|
||||
|-------|--------|--------|
|
||||
| `views/realestate/RealEstateDashboardView.tsx` | Registry mappt `dashboard` -> RealEstatePekView; nirgends importiert | loeschen ODER integrieren |
|
||||
| `views/realestate/RealEstateParcelsView.tsx` | Nicht in Registry, nirgends importiert | loeschen ODER integrieren |
|
||||
| `views/realestate/RealEstateProjectsView.tsx` | Nicht in Registry, nirgends importiert | loeschen ODER integrieren |
|
||||
| `views/commcoach/CommcoachDossierView.tsx` | Nicht in Registry; nur CSS von SessionView genutzt | loeschen ODER integrieren |
|
||||
| `views/trustee/TrusteePositionDocumentsView.tsx` | Nicht in Registry, nirgends importiert | loeschen ODER integrieren |
|
||||
| `billing/BillingDashboard.tsx` | Nicht in App.tsx-Routen, nirgends importiert | Routing klaeren / loeschen |
|
||||
| `billing/BillingTransactions.tsx` | Nicht in App.tsx-Routen, nirgends importiert | Routing klaeren / loeschen |
|
||||
| `billing/BillingUserView.tsx` | Nicht in App.tsx-Routen, nirgends importiert | Routing klaeren / loeschen |
|
||||
| `views/solutions/SolutionsView.tsx` | Noch in trustee-Registry (`solutions`); eigener Plan | in 4c deregistrieren + loeschen |
|
||||
| `chatworkflow` Dashboard/Runs/Files | Geroutet, aber reine PlaceholderViews | erst bei echter Implementierung migrieren |
|
||||
|
||||
Eingebettet (KEIN eigenes StackLayout, als Panel-Body in 5i behandeln): `TrusteePositionsView`, `TrusteeDocumentsView` (Tab-Inhalte in TrusteeDataTablesView via Wrapper).
|
||||
|
||||
## Migrations-Checkliste pro Seite
|
||||
|
||||
Erfahrungen aus der Migration von TrusteeDataTablesView und WorkflowAutomationHubPage.
|
||||
|
||||
### 1. Daten & API
|
||||
|
||||
- [ ] **Mandantenfilter**: "Alle" = kein `mandateId`-Param, Backend filtert per User-Mandatsliste.
|
||||
- [ ] **Daten-Reload bei Kontextwechsel**: `useEffect`/`useCallback`-Dependencies muessen `selectedMandateId` enthalten.
|
||||
- [ ] **Metriken/Dashboard konsistent mit Tabelle**: Gleicher Scope fuer Dashboard-Zahlen und Tabelle.
|
||||
|
||||
### 2. FK-Label-Resolution
|
||||
|
||||
- [ ] **displayField-Konvention**: `{fieldName}Label` (z.B. `workflowId` -> `workflowIdLabel`).
|
||||
- [ ] **enrichRowsWithFkLabels in ALLEN Pfaden**: Standard + filterValues.
|
||||
- [ ] **Cross-Mandate FK-Lookup**: `getRecord()` statt mandate-scoped Methoden.
|
||||
|
||||
### 3. FormGeneratorTable Integration
|
||||
|
||||
- [ ] **hookData.refetch als einziger Datenpfad**: `apiEndpoint` nur fuer CSV/Filtervalues.
|
||||
- [ ] **Keine redundanten Filter-Buttons**: FormGeneratorTable hat eingebaute Filter.
|
||||
- [ ] **Kein RBAC im UI**: Sichtbarkeit via Backend-Flags.
|
||||
|
||||
### 4. Backend RBAC (bei jeder Migration pruefen)
|
||||
|
||||
- [ ] **Kein isPlatformAdmin-Bypass fuer Lesezugriffe**.
|
||||
- [ ] **Fail-closed**: Fehlender Filter = leeres Ergebnis (`__impossible__`-Sentinel).
|
||||
- [ ] **mandateId-Validierung** gegen `userMandateIds`.
|
||||
|
||||
### 5. Fehlende API-Routen
|
||||
|
||||
- [ ] **Alle Frontend-API-Aufrufe pruefen**: Keine 405 Method Not Allowed.
|
||||
|
||||
### 6. Layout & UI
|
||||
|
||||
- [ ] **StackLayout + LayoutTabs verwenden**: URL als Source-of-Truth.
|
||||
- [ ] **Panel fuer collapsible Bloecke**.
|
||||
- [ ] **scrollMode-Integration**: min-height im document-Mode.
|
||||
- [ ] **Grouped Tabs**: Kategorie-Titel auf eigener Zeile.
|
||||
- [ ] **Loading/Error/Empty-States** (L1): pro Seite als Parameter belassen, NICHT generisch standardisieren.
|
||||
- [ ] **Scroll-Position** (L2): Position merken; wenn Ziel nicht mehr existiert, auf Top.
|
||||
- [ ] **Dark-Theme-Tokens** (L5): NUR CSS-Tokens, keine hardcoded Farben. Bestehende hardcoded Farben der beruehrten Seite gleich mitbereinigen.
|
||||
|
||||
### 7. Persistenz & State
|
||||
|
||||
- [ ] **Tab-State via URL**, nicht `useState`.
|
||||
- [ ] **Kontext-/Mandantenfilter via URL** (`?context=`), nicht `useState` (Referenz: Hub).
|
||||
- [ ] **Panel-Collapse-State** optional via `collapseKey` in localStorage.
|
||||
- [ ] **Keine stale Closures** bei Mandant-Wechsel.
|
||||
- [ ] **Tabellen-Filter/Suche** (L10): in localStorage persistieren. **Key MUSS `mandateId:instanceId` (bzw. `scopeKey`) enthalten** — sonst werden bei Mandantenwechsel fremde Filterwerte (FK-IDs) wiederhergestellt = Tenant-Leakage. Fail-closed: kein Scope -> keine Persistenz.
|
||||
|
||||
### 8. Keep-Alive (nur registrierte Seiten)
|
||||
|
||||
- [ ] **Pruefen** ob Seite in `config/keepAliveRoutes.tsx` registriert ist.
|
||||
- [ ] **Re-Measure** beim Wiedereinblenden (Hoehe war `display:none` -> 0) via generischem Hook (5-pre).
|
||||
- [ ] **matchLocation-Bedingung** erhalten (z.B. `?tab=editor`).
|
||||
- [ ] **scopeKey** als React-`key` beibehalten (Scope-Wechsel = Neu-Mount).
|
||||
- [ ] **Listener-Cleanup** zerstoert persistenten State nicht.
|
||||
|
||||
### 9. i18n (HARTE REGEL)
|
||||
|
||||
- [ ] **Keine hardcoded Strings** (L4): ALLE Chrome-Texte via `t()`. Subagenten duerfen niemals Klartext-Strings einsetzen.
|
||||
|
||||
### 10. Modals (NICHT in diesem Plan anfassen)
|
||||
|
||||
- [ ] **`modalOverlay`/Modal-Code NICHT migrieren** — laeuft im separaten Modal-Konsolidierungsplan. Nur Seiten-Layout (StackLayout/Panel/Tabs) anfassen, Modals unveraendert lassen, um Doppel-Diffs/Merge-Konflikte zu vermeiden.
|
||||
|
||||
## Entschiedene Logik-Fragen
|
||||
|
||||
| # | Thema | Entscheidung |
|
||||
|---|-------|-------------|
|
||||
| L1 | Loading/Error/Empty-States | Pro Seite als Parameter belassen, nicht generisch standardisieren |
|
||||
| L2 | Scroll-Position | Position merken; wenn Ziel nicht mehr existiert -> Top |
|
||||
| L3 | PanelLayout / verstellbare Splits | Collapse/Expand ist bereits generisch (Panel/LayoutTabs). Verstellbare Splits einmal generisch in Phase 6b bauen, danach keine Seitenanpassung mehr noetig |
|
||||
| L4 | i18n | HART: keine hardcoded Strings, alles via `t()` |
|
||||
| L5 | Dark-Theme-Tokens | Token-Pflicht, hardcoded Farben beruehrter Seiten gleich bereinigen |
|
||||
| L6 | ARIA/Focus | Generisch in den Primitiven (LayoutTabs/ViewStack/PanelLayout), nicht pro Seite |
|
||||
| L7 | Detail-Breadcrumb | ViewStack rendert bereits eigenen `detailHeader` (Back + Titel). Breadcrumb-Erweiterung NICHT in FeatureLayout (Hub ist Top-Level ohne FeatureLayout) — generisch im ViewStack/StackLayout.Header-Slot loesen, damit auch Top-Level-Seiten greifen. Niedrige Prio (aktuell nur Hub betroffen) |
|
||||
| L8 | ViewStack Toast | Generisch: Toast bei ungueltiger URL-Kombi nachruesten |
|
||||
| L9 | LayoutTabs `lazy` vs Keep-Alive | Generisch: Komponenten-Default bleibt `lazy=false` (nur aktiver Tab gemountet). Pro Seite `lazy` SETZEN bei Tab-Sets mit Formularen/Streams/State, da `lazy=true` besuchte Tabs gemountet haelt (State bleibt). Referenz: WorkflowAutomationHubPage setzt `lazy` |
|
||||
| L10 | Filter/Search-Persistenz | In localStorage persistieren; Key MUSS Scope (`mandateId:instanceId`) enthalten, sonst Tenant-Leakage. Fail-closed ohne Scope |
|
||||
| L11 | document.title | Generischer `useDocumentTitle`-Hook; setzt pro Seite den Zusatz, Ergebnis immer `${appName} - ${seitentitel}`. Hardcoded Auth-Titel (Login/Register/Reset) dabei bereinigen (auch i18n) |
|
||||
|
||||
Alle Logik-Fragen entschieden.
|
||||
|
||||
## Subagent-Strategie
|
||||
|
||||
Fuer Phase 5b-5j werden **composer-2.5-fast Subagenten** eingesetzt (ERST nach 5-pre + 6b):
|
||||
- Jeder Subagent migriert eine Batch von Seiten (z.B. alle Trustee-Views)
|
||||
- Auftrag pro Subagent: konkretes Pattern anwenden (adminPage -> StackLayout, manuelle Tabs -> LayoutTabs)
|
||||
- Migrations-Checkliste + Region-Spec (`2026-06-layout-regions.md`) als verbindliche Referenz mitgeben
|
||||
- Ergebnis: Liste aller geaenderter Dateien + Beschreibung
|
||||
- Hauptagent prueft Build + Lint nach jeder Batch
|
||||
|
||||
**Harte Regeln im Subagent-Auftrag (sonst inkonsistent):**
|
||||
- Keine hardcoded Strings — alles via `t()` (L4).
|
||||
- `modalOverlay`/Modals NICHT anfassen (separater Plan).
|
||||
- Tote Seiten (Dead-Code-Verifikation) NICHT migrieren.
|
||||
- StackLayout-Variant + Panel-Varianten exakt aus der Region-Spec uebernehmen, nicht raten.
|
||||
- Tab-/Kontext-State via URL, Filter via localStorage — nie `useState`.
|
||||
- Nur CSS-Tokens, keine hardcoded Farben (L5).
|
||||
|
||||
## Akzeptanzkriterien
|
||||
|
||||
| # | Kriterium (Given-When-Then) | Prio |
|
||||
|---|---------------------------|------|
|
||||
| 1 | Given Feature-Route auf iPhone SE (375x667) When Seite laedt Then Header scrollt weg, Tabelle bedienbar | must |
|
||||
| 2 | Given Feature-Route auf Desktop (1920x1080) When Seite laedt Then Tabelle scrollt intern, Header sichtbar | must |
|
||||
| 3 | Given Resize von Desktop zu schmalem Fenster When Breakpoint ueberschritten Then scrollMode wechselt live | must |
|
||||
| 4 | Given beliebige migrierte Seite When Tab gewechselt Then URL wird aktualisiert, kein useState fuer Tab | must |
|
||||
| 5 | Given `npx tsc --noEmit` When nach Abschluss Then 0 Fehler | must |
|
||||
| 6 | Given grep `adminPage\|adminPageFill\|pageHeader\|tableContainer` When nach Phase 7 Then 0 Treffer in Layout-Nutzung | must |
|
||||
| 7 | Given grep `UiComponents/Tabs` When nach Phase 7 Then 0 Treffer | must |
|
||||
|
||||
## Links
|
||||
|
||||
- Plan v3: `pagelayout_component_system_fd9fde3a.plan.md`
|
||||
- Solution-Plaene (eigener Scope): `c-work/0-ideas/2026-06-CustomerCases-step3-*`
|
||||
|
||||
## Abschluss
|
||||
|
||||
- [ ] b-reference/ui-nyla/layout.md erstellt
|
||||
- [ ] formgenerator.md "Page Layout Chain" aktualisiert
|
||||
- [ ] TOPICS.md aktualisiert
|
||||
- [ ] Aenderungs-Zusammenfassung aller migrierten Seiten
|
||||
- [ ] Dieses Dokument -> 4-done/ verschoben
|
||||
592
c-work/1-plan/2026-06-layout-regions.md
Normal file
592
c-work/1-plan/2026-06-layout-regions.md
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
<!-- status: build -->
|
||||
<!-- started: 2026-06-10 -->
|
||||
<!-- component: ui-nyla -->
|
||||
<!-- parent: 2026-06-layout-foundation.md -->
|
||||
|
||||
# Layout Regions — Seiten-Zuordnung
|
||||
|
||||
Referenz-Dokument zum [Layout Foundation Gesamtplan](2026-06-layout-foundation.md).
|
||||
Begriffe (Slot / Region / Variant) sind kanonisch in [`b-reference/ui-nyla/layout.md`](../../b-reference/ui-nyla/layout.md) definiert.
|
||||
|
||||
Jede Seite ist ein `StackLayout`; jeder Inhaltsblock im Body ist eine **Region** (`Panel`). Die **Regionstypen** (Panel-Varianten):
|
||||
|
||||
| Regionstyp (Panel-Variant) | Zweck | Collapse | Flex |
|
||||
|---------|-------|----------|------|
|
||||
| `card` | Info-Sektionen, Settings, allgemeine Bloecke | ja | nein |
|
||||
| `table` | FormGeneratorTable, bounded scroll | ja | flex:1 |
|
||||
| `dashboard` | KPI-Grid, Stats-Cards | ja | nein |
|
||||
| `toolbar` | Filter-Bar, Actions-Bar, kompakt | nein | nein |
|
||||
| `editor` | Code-Editor, Flow-Editor, Chat, Vollhoehe | ja | flex:1 |
|
||||
| `wizard` | Wizard-Schritte | nein | nein |
|
||||
|
||||
Seiten mit Tabs nutzen `LayoutTabs`. Modale Dialoge sind keine Regionen.
|
||||
|
||||
### StackLayout-Variant pro Seite (Pflichtangabe)
|
||||
|
||||
Jede Seite waehlt eine `StackLayout`-Variant (steuert Scroll-/Flex-Verhalten des Body). Regel nach Seitentyp:
|
||||
|
||||
| Seitentyp | StackLayout variant | Begruendung |
|
||||
|-----------|---------------------|-------------|
|
||||
| Tabelle/Liste (FormGeneratorTable) | `table` | bounded scroll, interner Tabellen-Scroll, mind. ein `flex:1`-Panel (`table`/`editor`) |
|
||||
| Wizard/Formular-Flow | `form` | natuerliche Hoehe, Seiten-Scroll |
|
||||
| Chat/Editor/Stream | `scroll` | Vollhoehe, eigener Scrollbereich |
|
||||
| KPI/Dashboard-Grid | `dashboard` | Karten-Grid, Seiten-Scroll |
|
||||
| **Tabbed-Seite** | **richtet sich nach dominantem Tab-Inhalt** | siehe Regel unten |
|
||||
|
||||
**Tabbed-Seiten-Regel (WICHTIG):** `variant="table"` setzt voraus, dass der Body ein `flex:1`-Panel (`table` oder `editor`) enthaelt — sonst scrollt die ganze Seite inkl. Header/Tabs statt nur des Bodys (sticky-Header-UX geht verloren). Daher:
|
||||
- Tab-Set mit mind. einem FormGeneratorTable-Tab -> `variant="table"`
|
||||
- Tab-Set nur aus `card`/`form`/`dashboard`-Panels (keine bounded Tabelle) -> **`variant="scroll"`**
|
||||
|
||||
Pro tabbed Seite ist der StackLayout-Variant unten **explizit** angegeben; nicht raten. Referenz: `TrusteeDataTablesView` -> `table` (Tabellen-Tabs), `WorkflowAutomationHubPage` -> `table` (Runs/Workflows-Tabellen).
|
||||
|
||||
### Referenz-Seiten (Gold-Standard, bereits migriert)
|
||||
|
||||
Diese zwei Seiten sind die verbindliche Vorlage fuer alle Subagenten:
|
||||
|
||||
#### TrusteeDataTablesView.tsx (Phase 4a)
|
||||
- `StackLayout variant="table"`
|
||||
- Slot Header: Breadcrumb (via FeatureLayout)
|
||||
- **LayoutTabs** (gruppiert, `preserveSearchParams`): Stammdaten / Dokumente / Konfiguration / Daten aus Buchhaltungssystem
|
||||
- Je Tab: Panel `table` (FormGeneratorTable via Wrapper; eingebettete Views OHNE eigenes StackLayout)
|
||||
|
||||
#### WorkflowAutomationHubPage.tsx (Phase 4b)
|
||||
- `StackLayout variant="table"`
|
||||
- Slot Header: Titel + Kontext-Selektor (Mandant), Kontext via URL `?context=`
|
||||
- **LayoutTabs** (`urlParam="tab"`, `lazy`): Workflows / Editor ([KEEP-ALIVE] `?tab=editor`) / Vorlagen / Durchlaeufe / Aufgaben
|
||||
- Tab Durchlaeufe: **ViewStack** (`entityParam="runId"`) list -> detail
|
||||
- Panel `dashboard` collapsible: Metrik-Karten
|
||||
- Panel `table`: RunsTab FormGeneratorTable
|
||||
- Tab Workflows: Panel `dashboard` collapsible (Metriken) + Panel `table` (WorkflowsTab)
|
||||
|
||||
### Keep-Alive (Persistenz beim Verlassen/Zurueckkehren)
|
||||
|
||||
Manche Seiten unmounten beim Verlassen **nicht** — sie behalten State, Scroll und laufende Prozesse (SSE, Streams). Registriert in `ui-nyla/src/config/keepAliveRoutes.tsx`; gerendert via `MainLayout.tsx` (per `display:none` versteckt statt unmounted).
|
||||
|
||||
Seiten mit **`[KEEP-ALIVE]`**-Markierung unten muessen bei der Migration beachten:
|
||||
- Beim Wiedereinblenden (`display:none` -> sichtbar) **Re-Measure/Re-Clamp** ausloesen (Hoehe war 0).
|
||||
- Resize-/Scroll-Listener-Cleanup darf den persistenten State nicht zerstoeren.
|
||||
- `scopeKey` (Mandant/Instanz) bleibt erhalten — beim Scope-Wechsel wird neu gemountet.
|
||||
|
||||
Bereits registriert: WorkspacePage (pro Scope), CommcoachSessionView (pro Session-Scope), AdminLanguagesPage, AdminDatabaseHealthPage, WorkflowAutomationHubPage (nur `?tab=editor`).
|
||||
|
||||
NEU zu registrieren (Teil dieser Migration): TeamsbotSessionView (pro Session-Scope), RedmineBrowserView.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5b — Trustee-Views
|
||||
|
||||
### TrusteeAbschlussView.tsx
|
||||
- **LayoutTabs**: Jahresabschluss, MWST-Abrechnung, Reporting Behoerden
|
||||
- Je Tab:
|
||||
- Panel `card`: Beschreibungstext / Coming-Soon-InfoBox
|
||||
- Panel `card`: Workflow-Info + PeriodPicker + Aktion + Status
|
||||
|
||||
### TrusteeAccountingSettingsView.tsx
|
||||
- **LayoutTabs**: Verbindungseinstellungen, Buchhaltungsdaten importieren
|
||||
- Tab Verbindungseinstellungen:
|
||||
- Panel `card` collapsible: Status-Banner
|
||||
- Panel `wizard`: 3-Schritt-Wizard (Buchhaltungssystem, Zugangsdaten, Aktionen)
|
||||
- Tab Buchhaltungsdaten importieren:
|
||||
- Panel `card`: Letzter-Import-Status
|
||||
- Panel `card`: Import-Formular (PeriodPicker + Aktionen + Fortschritt)
|
||||
- Panel `card`: Aktueller Datenbestand
|
||||
|
||||
### TrusteeAnalyseView.tsx
|
||||
- **LayoutTabs**: Budget-Vergleich, KPI-Dashboard, Cashflow-Rechnung, Prognose
|
||||
- Je Tab:
|
||||
- Panel `card`: Beschreibungstext
|
||||
- Panel `card`: Workflow-Info + Upload (Budget) + PeriodPicker + Aktion + Status
|
||||
|
||||
### TrusteeDashboardView.tsx
|
||||
- Panel `dashboard`: Metriken-Grid (Positionen, Dokumente, Buchhaltung, Rolle)
|
||||
- Panel `card`: QuickActionBoard
|
||||
- Panel `card` collapsible: Instanz-Details (Info-Grid)
|
||||
|
||||
### TrusteeDocumentsView.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neues Dokument)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### TrusteeExpenseImportView.tsx
|
||||
- Panel `card`: Status-Box (Workflow aktiv/inaktiv)
|
||||
- Panel `wizard`: 4-Schritt-Setup (Microsoft-Verbindung, SharePoint, Ordner-Browser, Speichern)
|
||||
|
||||
### TrusteeImportProcessView.tsx
|
||||
- **LayoutTabs**: Belege verarbeiten, Beleg hochladen, Daten einlesen
|
||||
- Tab Belege: eingebettetes TrusteeExpenseImportView
|
||||
- Tab Upload: eingebettetes TrusteeScanUploadView
|
||||
- Tab Daten einlesen: Weiterleitung zu Settings
|
||||
|
||||
### TrusteeInstanceRolesView.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren)
|
||||
- Panel `card`: Erklaerungstext
|
||||
- Panel `card`: Rollen-Liste (expandierbare Rollen-Cards mit AccessRulesEditor)
|
||||
|
||||
### TrusteePositionDocumentsView.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neue Verknuepfung)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### TrusteePositionsView.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neue Position)
|
||||
- Panel `table`: FormGeneratorTable (mit Batch-Actions)
|
||||
|
||||
### TrusteeScanUploadView.tsx
|
||||
- Panel `card`: Beschreibungstext + Pipeline-Status
|
||||
- Panel `card`: Drag-and-Drop Upload-Zone + Dateiliste + Start-Button
|
||||
|
||||
### dataTables/TrusteeDataTab.tsx
|
||||
- Panel `toolbar`: Aktualisieren-Button
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
---
|
||||
|
||||
## Phase 5c — Admin-Seiten
|
||||
|
||||
### AdminUsersPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Zugriffsübersicht, Einladungen, Aktualisieren, Neuer Benutzer)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminUserMandatesPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Mandant-Select, Aktualisieren, Benutzer hinzufügen)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminUserAccessOverviewPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Benutzer-Select, Aktualisieren)
|
||||
- Panel `card`: User-Info-Box (Name, E-Mail, Badges)
|
||||
- **LayoutTabs**: Uebersicht, UI-Zugriff, Daten-Zugriff, Ressourcen
|
||||
- Je Tab: Panel `card` mit Mandant-Hierarchie bzw. Zugriffs-Tabellen
|
||||
|
||||
### AdminMandatesPage.tsx
|
||||
- Panel `toolbar`: Header-Actions
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminMandateRolesPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Mandant, Scope, Aktualisieren, Neue Rolle)
|
||||
- Panel `card`: Info-Box (System-Templates)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminMandateRolePermissionsPage.tsx
|
||||
- Panel `toolbar`: Header-Actions + Filter-Bar (Mandant, Bereich)
|
||||
- Panel `card`: Info-Box
|
||||
- Panel `card`: Rollen-Liste (expandierbare roleCards mit AccessRulesEditor)
|
||||
|
||||
### AdminLogsPage.tsx
|
||||
- Panel `toolbar`: Controls-Bar (Anzahl, Laden, Auto-Refresh)
|
||||
- Panel `editor`: Log-Container (farbcodierte Log-Zeilen)
|
||||
|
||||
### AdminLanguagesPage.tsx **[KEEP-ALIVE]**
|
||||
- Panel `toolbar`: Toolbar (Reload, Suche, Aktionen, Export, Import, Neue Sprache)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
- Keep-Alive: bleibt persistent (laufende Uebersetzungs-Prozesse/Progress-Overlay)
|
||||
|
||||
### AdminInvitationsPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Mandant, Checkboxen, Aktualisieren, Neue Einladung)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminFeatureRolesPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Feature-Select, Aktualisieren, Neue Rolle)
|
||||
- Panel `card`: Info-Box (Template-Rollen)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminFeatureInstanceUsersPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Mandant/Instanz-Select, Aktualisieren, Benutzer hinzufügen)
|
||||
- Panel `card`: Info-Boxen (Kontext, Verfuegbare Rollen)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminFeatureAccessPage.tsx
|
||||
- Panel `toolbar`: Filter-Bar (Mandant-Select, Aktualisieren, Neue Instanz)
|
||||
- Panel `card`: Info-Box (Verfuegbare Features)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### AdminDemoConfigPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren)
|
||||
- Panel `dashboard`: Config-Card-Grid
|
||||
|
||||
### AdminDatabaseHealthPage.tsx **[KEEP-ALIVE]**
|
||||
- Keep-Alive: bleibt persistent (laufende Scan-/Cleanup-/Migration-Prozesse mit Logs)
|
||||
- **LayoutTabs**: Statistiken, Orphan Cleanup, Legacy Cleanup, Migration
|
||||
- Tab Statistiken:
|
||||
- Panel `toolbar`: Filter-Bar (DB-Select, Aktualisieren)
|
||||
- Panel `card`: Summary-Zeile
|
||||
- Panel `table`: FormGeneratorTable
|
||||
- Tab Orphans:
|
||||
- Panel `toolbar`: Filter-Bar (DB, Checkboxen, Scan, Bereinigen)
|
||||
- Panel `card`: Warn-Info-Box
|
||||
- Panel `table`: FormGeneratorTable
|
||||
- Tab Legacy Cleanup:
|
||||
- Panel `toolbar`: Toolbar (Scan, Checkboxen, Loeschen)
|
||||
- Panel `card`: Warn-Info-Box
|
||||
- Panel `table`: FormGeneratorTable
|
||||
- Tab Migration:
|
||||
- Panel `card`: Backup-Section
|
||||
- Panel `card`: Restore-Section (Drop-Zone, Validierung, Import)
|
||||
|
||||
### AccessManagementHub.tsx
|
||||
- Panel `toolbar`: Filter-Bar + View-Mode-Switch + Nav-Links
|
||||
- Listenansicht:
|
||||
- Panel `dashboard`: Overview-Stats-Cards
|
||||
- Panel `dashboard`: Feature-Instanz-Grid
|
||||
- Hierarchieansicht:
|
||||
- Panel `card`: InstanceHierarchyView (Baumstruktur)
|
||||
|
||||
### PermissionMatrix.tsx
|
||||
- Panel `table`: Benutzer-Rollen-Matrix-Tabelle
|
||||
- Panel `toolbar`: Footer (Benutzer hinzufuegen)
|
||||
|
||||
### InstanceHierarchyView.tsx
|
||||
- Panel `card`: Expandierbare Mandant/Feature/Instanz-Baumstruktur
|
||||
|
||||
### InstanceDetailModal.tsx
|
||||
- Modal (kein Panel) mit internen LayoutTabs:
|
||||
- **LayoutTabs**: Benutzer, Rollen, Einstellungen
|
||||
- Tab Benutzer: PermissionMatrix
|
||||
- Tab Rollen: Rollen-Liste + Sync
|
||||
- Tab Einstellungen: FormGeneratorForm
|
||||
|
||||
### wizards/AdminMandateWizardPage.tsx
|
||||
- Panel `wizard`: 4-Schritt-Wizard (Mandant, Benutzer, Feature-Instanzen, Feature-Benutzer)
|
||||
- Panel `toolbar`: Step-Indicator + Navigation
|
||||
|
||||
### wizards/AdminInvitationWizardPage.tsx
|
||||
- Panel `wizard`: 4-Schritt-Wizard (Art, Mandant, Einladungen, Zusammenfassung)
|
||||
- Panel `toolbar`: Step-Indicator + Navigation
|
||||
|
||||
### wizards/FeatureInstanceWizard.tsx
|
||||
- Modal mit Panel `wizard`: 3-Schritt-Wizard (Instanz erstellen, Rollen, Benutzer)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5d — Basedata-Seiten
|
||||
|
||||
### ConnectionsPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neue Verbindung)
|
||||
- Panel `card` collapsible: Knowledge-Sync-Banner
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### FilesPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Tree/Table-Toggles, Aktualisieren)
|
||||
- Split-Layout (Phase 6b PanelLayout):
|
||||
- Panel `card`: FormGeneratorTree (Eigene + Geteilt)
|
||||
- Panel `table`: FormGeneratorTable (mit View-Mode-Toggle + Upload)
|
||||
|
||||
### PromptsPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neuer Prompt)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
---
|
||||
|
||||
## Phase 5e — Feature-Views
|
||||
|
||||
### Commcoach
|
||||
|
||||
#### CommcoachAssistantView.tsx
|
||||
- Panel `wizard`: Wizard (Modul-Typ, Thema, Persona, KPI, Zusammenfassung)
|
||||
- Panel `toolbar`: Wizard-Header (Schritt-Indikator, Zurueck/Weiter)
|
||||
|
||||
#### CommcoachDashboardView.tsx
|
||||
- Panel `dashboard`: KPI-Grid (Streak, Sessions, Score, Zielfortschritt)
|
||||
- Panel `card` collapsible: Aktive Coaching-Themen (Context-Karten-Grid)
|
||||
- Panel `card` collapsible: Level/Auszeichnungen (Badge-Grid)
|
||||
- Panel `card` collapsible: Tipp des Tages
|
||||
|
||||
#### CommcoachDossierView.tsx **[TOT — nicht geroutet; Phase 7 klaeren, NICHT migrieren]**
|
||||
- Split-Layout (Phase 6b PanelLayout):
|
||||
- Panel `card`: UnifiedDataBar-Sidebar (Dateien, Quellen)
|
||||
- Hauptbereich mit LayoutTabs: Coaching, Aufgaben, Sessions, Bewertungen
|
||||
- Tab Coaching: Panel `editor` (Chat-Stream + Eingabe)
|
||||
- Tab Aufgaben: Panel `card` (Task-Liste)
|
||||
- Tab Sessions: Panel `card` (Timeline)
|
||||
- Tab Scores: Panel `card` (Dimension-Balken)
|
||||
|
||||
#### CommcoachModulesView.tsx
|
||||
- Panel `toolbar`: Header (Filter, Neues Modul)
|
||||
- Panel `card`: Modul-Liste (expandierbare Karten mit Session-Zeilen)
|
||||
|
||||
#### CommcoachSessionView.tsx **[KEEP-ALIVE]**
|
||||
- Keep-Alive: bleibt persistent pro Session-Scope (laufende Voice-/Chat-Session, SSE). `shellOverflowHidden: false`
|
||||
- Split-Layout (Phase 6b PanelLayout):
|
||||
- Panel `card`: UDB-Sidebar
|
||||
- Panel `editor`: Session-Chat (Header, Nachrichten, Eingabe)
|
||||
|
||||
#### CommcoachSettingsView.tsx
|
||||
- **LayoutTabs**: Allgemein, Gespraechspartner
|
||||
- Tab Allgemein:
|
||||
- Panel `card`: Einstellungen-Formular (Stimme, Erinnerungen)
|
||||
- Tab Gespraechspartner:
|
||||
- Panel `toolbar`: Header-Actions
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### Teamsbot
|
||||
|
||||
#### TeamsbotAssistantView.tsx
|
||||
- Panel `wizard`: Wizard (Modul, Meeting-Config, Bot-Name, Zusammenfassung)
|
||||
- Panel `toolbar`: Wizard-Header (Schritt-Indikator)
|
||||
|
||||
#### TeamsbotDashboardView.tsx
|
||||
- Panel `dashboard`: Hero-Header + Quick-Actions
|
||||
- Panel `dashboard`: KPI-Grid (Module, Sitzungen, Segmente)
|
||||
- Panel `card` collapsible: Module nach Aktivitaet (Modul-Karten-Grid)
|
||||
- Panel `card` collapsible: Aktive Sitzungen (Session-Zeilen)
|
||||
|
||||
#### TeamsbotModulesView.tsx
|
||||
- Panel `toolbar`: Header (Modul anlegen, Meeting starten)
|
||||
- Panel `card`: Modul-Liste (expandierbare Karten mit Session-Tabelle)
|
||||
|
||||
#### TeamsbotSessionView.tsx **[KEEP-ALIVE — NEU zu registrieren]**
|
||||
- Keep-Alive: muss NEU in `keepAliveRoutes.tsx` aufgenommen werden (laufende Live-Session, Transkript-SSE, Bot-Antworten). Analog zu CommcoachSessionView, pro Session-Scope.
|
||||
- Split-Layout (Phase 6b PanelLayout):
|
||||
- Panel `card`: UDB-Sidebar
|
||||
- Panel `card`: Regieanweisungen-Panel
|
||||
- Panel `editor`: Split-Content (Transkript + Bot-Antworten)
|
||||
|
||||
#### TeamsbotSettingsView.tsx
|
||||
- **LayoutTabs**: Bot-Einstellungen, System-Bots
|
||||
- Tab Bot-Einstellungen:
|
||||
- Panel `card`: Settings-Card (Identitaet, AI-Verhalten, Sprache, Erweitert)
|
||||
- Tab System-Bots:
|
||||
- Panel `table`: Bot-Tabelle + Anlegen-Formular
|
||||
|
||||
### RealEstate
|
||||
|
||||
#### RealEstateDashboardView.tsx **[TOT — Registry mappt `dashboard`->PekView; Phase 7]**
|
||||
- Panel `dashboard`: Stats-Grid (Projekte, Parzellen, Rollen)
|
||||
- Panel `card` collapsible: Instanz-Details (Info-Grid)
|
||||
|
||||
#### RealEstateParcelsView.tsx **[TOT — nicht geroutet; Phase 7]**
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neue Parzelle)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
#### RealEstatePekView.tsx (Registry: `dashboard`)
|
||||
- Panel `card`: PekLocationInput (Adresseingabe)
|
||||
- Panel `editor`: PekMapView (Karte)
|
||||
|
||||
#### RealEstateProjectsView.tsx **[TOT — nicht geroutet; Phase 7]**
|
||||
- Panel `toolbar`: Header-Actions (Aktualisieren, Neues Projekt)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
#### RealEstateInstanceRolesPlaceholder.tsx
|
||||
- Panel `card`: Info-Sektion (Hinweistext + Links)
|
||||
|
||||
#### pek/PekMapView.tsx (eingebettet in RealEstatePekView, KEIN eigenes StackLayout)
|
||||
- Panel `toolbar`: Checkbox-Zeile (Alle Parzellen, Abwaehlen)
|
||||
- Panel `editor`: Karten-Container (MapView)
|
||||
- Panel `card`: ParcelInfoPanel (Slide-out)
|
||||
|
||||
#### pek/PekLocationInput.tsx (eingebettet in RealEstatePekView, KEIN eigenes StackLayout)
|
||||
- Panel `toolbar`: Adress-/Parzellen-Eingabe + Suchen + Meine Position
|
||||
|
||||
### Redmine
|
||||
|
||||
#### RedmineBrowserView.tsx **[KEEP-ALIVE — NEU zu registrieren]**
|
||||
- Keep-Alive: muss NEU in `keepAliveRoutes.tsx` aufgenommen werden (gesetzte Filter, ausgewaehltes Ticket, unsaved Edits im TicketEditor).
|
||||
- Panel `toolbar`: Browser-Header (Titel, Ticket-Zaehler)
|
||||
- Panel `toolbar`: Filter-Bar (Period, Status, Tracker, Zuweisung, Sprint)
|
||||
- Split-Layout (Phase 6b PanelLayout):
|
||||
- Panel `table`: Ticket-Baum-Grid
|
||||
- Panel `editor`: RedmineTicketEditor
|
||||
|
||||
#### RedmineSettingsView.tsx
|
||||
- Panel `card` collapsible: Verbindung (URL, Projekt, API-Key, Aktionen)
|
||||
- Panel `card` collapsible: Mirror-Sync (KV-Grid, Sync-Buttons)
|
||||
|
||||
#### RedmineStatsView.tsx
|
||||
- Panel `toolbar`: Heading/Untertitel
|
||||
- Panel `card`: FormGeneratorReport (KPI-Grid, Charts, Filter)
|
||||
|
||||
#### RedmineTicketEditor.tsx (eingebettet in RedmineBrowserView `editor`-Panel, KEIN eigenes StackLayout)
|
||||
- Panel `toolbar`: Editor-Header (Tracker, Ticket-ID, Titel, Link)
|
||||
- Panel `card`: Formular-Grid (alle Felder)
|
||||
- Panel `toolbar`: Button-Row (Zuruecksetzen, Speichern)
|
||||
|
||||
### Neutralization
|
||||
|
||||
#### NeutralizationView.tsx
|
||||
- **LayoutTabs**: Konfiguration, Spielwiese
|
||||
- Tab Konfiguration:
|
||||
- Panel `card`: Namen-Textarea + Speichern
|
||||
- Tab Spielwiese:
|
||||
- Panel `card`: Datei-Upload
|
||||
- Panel `card`: Text-Eingabe/Ausgabe (Neutralisieren/Aufloesen)
|
||||
- Panel `card`: SharePoint Quell/Ziel-Pfade
|
||||
|
||||
---
|
||||
|
||||
## Phase 5f — Billing-Seiten
|
||||
|
||||
### BillingDataView.tsx
|
||||
- Panel `toolbar`: Kontext-Filter (Scope-Dropdown, Checkbox)
|
||||
- **LayoutTabs**: Uebersicht, Diagramme, Transaktionen
|
||||
- Tab Uebersicht: Panel `dashboard` (FormGeneratorReport KPI-Grid)
|
||||
- Tab Diagramme: Panel `card` (Chart-Mode-Toggle, Gruppierung, FormGeneratorReport)
|
||||
- Tab Transaktionen: Panel `table` (FormGeneratorTable)
|
||||
|
||||
### BillingAdmin.tsx
|
||||
- Panel `toolbar`: MandateSelector
|
||||
- **LayoutTabs**: Abonnement, Einstellungen, Guthaben aufladen
|
||||
- Tab Abonnement: Panel `card` (SubscriptionTab)
|
||||
- Tab Einstellungen: Panel `card` (SettingsEditor)
|
||||
- Tab Guthaben: Panel `card` (CreditAdder + StripeTopUp + AccountsOverview)
|
||||
|
||||
### BillingMandateView.tsx
|
||||
- Panel `card` collapsible: Mandanten-Guthaben (MandateBalanceTable)
|
||||
- Panel `card` collapsible: Transaktionen (TransactionTable)
|
||||
|
||||
### BillingUserView.tsx **[TOT — nicht geroutet; Phase 7]**
|
||||
- Panel `toolbar`: Filter-Bar (Mandant/Benutzer)
|
||||
- Panel `card` collapsible: Benutzer-Guthaben (UserBalanceTable)
|
||||
- Panel `card` collapsible: Transaktionen (UserTransactionTable)
|
||||
|
||||
### BillingTransactions.tsx **[TOT — nicht geroutet; Phase 7]**
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### BillingDashboard.tsx **[TOT — nicht geroutet; Phase 7]**
|
||||
- Panel `dashboard`: Guthaben-Grid (BalanceCards)
|
||||
- Panel `card` collapsible: Nutzungsstatistik (PeriodPicker + Charts)
|
||||
|
||||
### BillingNav.tsx (Subkomponente, KEIN eigenes StackLayout)
|
||||
- Panel `toolbar`: Route-Navigation (NavLinks)
|
||||
|
||||
### AdminSubscriptionsPage.tsx
|
||||
- Panel `toolbar`: Header-Actions (Enterprise-Abo erstellen)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### SubscriptionTab.tsx
|
||||
- Panel `card`: Aktuelles Abonnement
|
||||
- Panel `card`: Geplanter Nachfolgeplan
|
||||
- Panel `dashboard`: Verfuegbare Plaene (PlanCard-Grid)
|
||||
|
||||
### EnterpriseDialog.tsx
|
||||
- Modal (kein Panel): Formular (Mandant, Zeitraum, Preis, Limits)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5g — Top-Level-Seiten
|
||||
|
||||
### Dashboard.tsx
|
||||
- Panel `card`: OnboardingAssistant
|
||||
- Panel `dashboard`: Mandanten-Sektionen (InstanceCard-Grid pro Mandant)
|
||||
|
||||
### Settings.tsx
|
||||
- **LayoutTabs**: Profil, Darstellung, Stimme & Sprache, Sicherheit, Datenschutz
|
||||
- Tab Profil: Panel `card` (User-Info, Applikations-Info)
|
||||
- Tab Darstellung: Panel `card` (Theme-Toggle, Sprach-Select)
|
||||
- Tab Stimme: Panel `card` (STT-Sektion, TTS-Stimmen-Tabelle)
|
||||
- Tab Sicherheit: Panel `card` (MFA-Settings)
|
||||
- Tab Datenschutz: Panel `card` (GDPR-Link, Neutralization-Mappings)
|
||||
|
||||
### Store.tsx
|
||||
- Panel `card`: Subscription-Banner
|
||||
- Panel `dashboard`: Feature-Card-Grid
|
||||
|
||||
### IntegrationsOverviewPage.tsx
|
||||
- Panel `card`: Intro
|
||||
- Panel `card`: PORTA-Architektur-Diagramm (3 Schichten)
|
||||
|
||||
### ComplianceAuditPage.tsx
|
||||
- Panel `toolbar`: MandateSelector
|
||||
- **LayoutTabs**: Audit-Log, AI-Datenfluss, Neutralisierung, Statistiken
|
||||
- Tab Audit-Log: Panel `table` (FormGeneratorTable)
|
||||
- Tab AI-Datenfluss: Panel `table` (FormGeneratorTable)
|
||||
- Tab Statistiken: Panel `dashboard` (KPI-Grid + Charts)
|
||||
- Tab Neutralisierung: Panel `table` (FormGeneratorTable)
|
||||
|
||||
### RagInventoryPage.tsx
|
||||
- Panel `toolbar`: Kontext-Filter (Scope-Select, Checkbox)
|
||||
- Panel `card`: Totals-Leiste
|
||||
- Panel `card`: Verbindungs-Karten (je Verbindung)
|
||||
- Panel `card`: Feature-Daten-Karten (je Feature-Instanz)
|
||||
|
||||
### GDPR.tsx
|
||||
- Panel `card`: Datenrechte (3 Action-Cards)
|
||||
- Panel `card`: Verarbeitungsinformationen (Info-Grid)
|
||||
|
||||
### FeatureView.tsx
|
||||
- Kein Panel (duenner Router-Wrapper, CSS pruefen)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5g2 — Auth-Seiten
|
||||
|
||||
### Login.tsx, Register.tsx, PasswordResetRequest.tsx, Reset.tsx, InvitePage.tsx
|
||||
- Eigenstaendiges Auth-Layout ohne MainLayout
|
||||
- Kein Panel noetig — nur CSS-Modernisierung pruefen
|
||||
|
||||
---
|
||||
|
||||
## Phase 5h — WorkflowAutomation Views + Sub-Tabs
|
||||
|
||||
### WorkflowTemplatesPage.tsx
|
||||
- Panel `toolbar`: Header (Scope-Filter-Buttons, Aktualisieren)
|
||||
- Panel `table`: FormGeneratorTable
|
||||
|
||||
### WorkflowEditorPage.tsx
|
||||
- Panel `editor`: FlowEditor (delegiert an Komponente)
|
||||
|
||||
### TemplatesTab.tsx
|
||||
- Duenner Wrapper um WorkflowTemplatesPage (kein eigenes Panel)
|
||||
|
||||
### EditorTab.tsx **[KEEP-ALIVE]**
|
||||
- Keep-Alive: WorkflowAutomationHubPage bleibt persistent, wenn `?tab=editor` aktiv (unsaved Graph-Edits, FlowEditor-State). Migration muss `matchLocation`-Bedingung erhalten.
|
||||
- Duenner Wrapper um WorkflowEditorPage (kein eigenes Panel)
|
||||
|
||||
### TasksTab.tsx
|
||||
- Panel `toolbar`: Header (Pending-Count, Aktualisieren)
|
||||
- Panel `card`: Pending-Task-Cards (Workflow-Label, Aktionen)
|
||||
- Panel `card` collapsible defaultCollapsed: Abgeschlossene Aufgaben
|
||||
|
||||
### RunDetailTab.tsx
|
||||
- Panel `toolbar`: Zurueck-Button
|
||||
- Panel `card`: Run-Titel + Metadaten + Error-Banner
|
||||
- Panel `card` collapsible: Ergebnisse (File-Downloads)
|
||||
- Panel `card`: Schritte (Accordion-Liste)
|
||||
- Panel `card` collapsible: Sonstige Dokumente
|
||||
|
||||
---
|
||||
|
||||
## Phase 5i — Trustee Sub-Komponenten
|
||||
|
||||
### dataTables/TrusteeDataTab.tsx
|
||||
- (siehe oben, bereits dokumentiert)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5j — Workspace-Views
|
||||
|
||||
### WorkspacePage.tsx **[KEEP-ALIVE]**
|
||||
- Keep-Alive: bleibt persistent pro Mandant/Instanz-`scopeKey` (laufender Chat, Streams, offene Dateien). `requireMandateForMount: false`. Re-Measure der Split-Panels beim Wiedereinblenden zwingend.
|
||||
- Split-Layout (Phase 6b PanelLayout, 3-Spalten):
|
||||
- Links: Panel `card` collapsible (UnifiedDataBar)
|
||||
- Mitte: Panel `editor` (ChatStream + WorkspaceInput)
|
||||
- Rechts mit LayoutTabs: Aktivitaet, Vorschau
|
||||
- Tab Aktivitaet: Panel `card` (ToolActivityLog)
|
||||
- Tab Vorschau: Panel `card` (FilePreview)
|
||||
|
||||
### WorkspaceEditorPage.tsx
|
||||
- Panel `toolbar`: Header (Zurueck, Titel, Accept-All/Reject-All)
|
||||
- Panel `toolbar`: File-Tab-Bar
|
||||
- Panel `editor`: Monaco DiffEditor
|
||||
- Panel `toolbar`: Footer (Datei-Metadaten, Accept/Reject)
|
||||
|
||||
### WorkspaceSettingsPage.tsx
|
||||
- Panel `card`: WorkspaceGeneralSettings (scrollbar)
|
||||
|
||||
### WorkspaceGeneralSettings.tsx
|
||||
- Panel `card`: Agenten-Konfiguration (Max Rounds, Reset)
|
||||
- Panel `card`: KI-Einstellungen (Neutralisierung, Provider, Modelle)
|
||||
|
||||
### WorkspaceInput.tsx
|
||||
- Panel `toolbar`: Attachment-Chips (Dateien, Datenquellen)
|
||||
- Panel `toolbar`: Prompt-Eingabe-Zeile (Textarea, Upload, Provider, Voice, Send)
|
||||
|
||||
### ChatStream.tsx
|
||||
- Panel `editor`: Scrollbare Nachrichtenliste
|
||||
|
||||
### FilePreview.tsx
|
||||
- Panel `card`: Datei-Metadaten-Header + Content-Bereich
|
||||
|
||||
### NeutralizationPanel.tsx
|
||||
- Panel `card` collapsible: Neutralisierter Text (Accordion)
|
||||
- Panel `card` collapsible: Datenquellen-Liste
|
||||
- Panel `table`: Platzhalter-Mappings-Tabelle
|
||||
|
||||
### ToolActivityLog.tsx
|
||||
- Panel `card`: Expandierbare Activity-Cards (Tool-Name, Status, Args, Result)
|
||||
108
c-work/1-plan/2026-06-modal-consolidation.md
Normal file
108
c-work/1-plan/2026-06-modal-consolidation.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<!-- status: plan -->
|
||||
<!-- started: 2026-06-10 -->
|
||||
<!-- component: ui-nyla -->
|
||||
|
||||
# Modal-Konsolidierung
|
||||
|
||||
## Beschreibung und Kontext
|
||||
|
||||
Aktuell gibt es 3 verschiedene Modal-Implementierungen im System. Das ist nicht wartbar und fuehrt zu inkonsistentem Verhalten (Backdrop, ESC-Handling, Focus-Trap, Accessibility).
|
||||
|
||||
## Ist-Zustand
|
||||
|
||||
### 3 Modal-Patterns
|
||||
|
||||
| Pattern | Komponente | Nutzung |
|
||||
|---------|-----------|---------|
|
||||
| `useConfirm()` Hook | `ConfirmDialog` | 6 Seiten (Bestaetigungs-Dialoge) |
|
||||
| `usePrompt()` Hook | `PromptDialog` | 4 Seiten (Text-Eingabe-Dialoge) |
|
||||
| `<Modal>` Komponente | `UiComponents/Modal` | 1 Seite (EnterpriseDialog) |
|
||||
| `div.modalOverlay` + CSS | Per Seite dupliziert | ~25 Seiten |
|
||||
|
||||
### modalOverlay mit FormGeneratorForm (~15 Seiten)
|
||||
|
||||
Overlay-Container ist per CSS-Modul dupliziert (`Admin.module.css`, `TrusteeViews.module.css`, etc.), Inhalt ist `FormGeneratorForm` — halbwegs standardisiert.
|
||||
|
||||
Betroffene Seiten:
|
||||
- Admin: AdminUsersPage, AdminUserMandatesPage, AdminMandatesPage, AdminMandateRolesPage, AdminInvitationsPage, AdminFeatureRolesPage, AdminFeatureInstanceUsersPage, AdminFeatureAccessPage
|
||||
- Trustee: TrusteeDataTab, TrusteeDocumentsView, TrusteePositionsView, TrusteePositionDocumentsView
|
||||
- Basedata: ConnectionsPage, FilesPage, PromptsPage
|
||||
- Feature: CommcoachSettingsView, RealEstateParcelsView, RealEstateProjectsView
|
||||
|
||||
### modalOverlay mit Custom-Inhalt (~10 Seiten)
|
||||
|
||||
Diese Seiten haben Modale ohne FormGeneratorForm:
|
||||
|
||||
| Seite | Inhalt |
|
||||
|-------|--------|
|
||||
| RunsTab | Run-Tracing Detail-Ansicht |
|
||||
| NeutralizationView | SharePoint Ordner-Browser |
|
||||
| InstanceDetailModal | Multi-Tab-Modal (UiComponents/Tabs) mit verschachtelten Sub-Modalen |
|
||||
| AdminMandateRolePermissionsPage | Duplikate-Cleanup mit Custom-Tabellen |
|
||||
| AdminFeatureAccessPage | Feature-Button-Grid zur Auswahl |
|
||||
| AdminInvitationsPage | URL-Anzeige mit Copy-Button |
|
||||
| AdminFeatureRolesPage | AccessRulesEditor (Berechtigungen) |
|
||||
| FeatureInstanceWizard | 3-Schritt-Wizard im Modal |
|
||||
| ComplianceAuditPage | Content-View (Input/Output) |
|
||||
| TeamsbotModulesView | Inline confirmDialog (nicht Hook) |
|
||||
| CommcoachModulesView | Inline confirmDialog (nicht Hook) |
|
||||
| Settings | ProfileEditModal (mit FormGeneratorForm) |
|
||||
|
||||
## Ziel
|
||||
|
||||
- **Ein** Modal-Container fuer alle Anwendungsfaelle
|
||||
- Backdrop, ESC, Focus-Trap, ARIA (`role="dialog"`, `aria-modal`) konsistent
|
||||
- FormGeneratorForm-Modale: Zero-Boilerplate (kein manueller Overlay-Code auf der Seite)
|
||||
- Custom-Modale: Gleicher Container, freier Inhalt
|
||||
- `useConfirm` und `usePrompt` als spezialisierte Wrapper bleiben (sind bereits OK)
|
||||
|
||||
## Entscheidungen
|
||||
|
||||
| Datum | Entscheidung | Begruendung |
|
||||
|-------|-------------|------------|
|
||||
| 2026-06-10 | Separater Plan, nicht Teil des Layout-Refactoring | Modale sind Overlays, keine Seitenregionen. Unabhaengig loesbar. |
|
||||
|
||||
## Vorgeschlagene Architektur
|
||||
|
||||
### Bestehende `<Modal>` Komponente erweitern
|
||||
|
||||
`UiComponents/Modal/Modal.tsx` existiert bereits, wird aber nur von `EnterpriseDialog.tsx` genutzt. Diese Komponente wird zum Standard.
|
||||
|
||||
### Stufen
|
||||
|
||||
| Stufe | Aktion |
|
||||
|-------|--------|
|
||||
| 1 | `<Modal>` Komponente pruefen: hat sie Backdrop, ESC, Focus-Trap, ARIA, Groessen-Varianten? Fehlende Features ergaenzen. |
|
||||
| 2 | `useFormModal()` Hook erstellen: Oeffnet `<Modal>` mit `<FormGeneratorForm>` — ersetzt 15 Seiten mit modalOverlay+FormGeneratorForm |
|
||||
| 3 | Custom-Modale auf `<Modal>` migrieren (10 Seiten) |
|
||||
| 4 | `modalOverlay`-CSS aus allen CSS-Modulen entfernen |
|
||||
| 5 | `TeamsbotModulesView` und `CommcoachModulesView` auf `useConfirm()` Hook umstellen |
|
||||
|
||||
## Betroffene Module
|
||||
|
||||
- `components/UiComponents/Modal/Modal.tsx` + `.module.css` — erweitern
|
||||
- Neuer Hook: `hooks/useFormModal.ts`
|
||||
- ~25 Seiten: modalOverlay entfernen, durch `<Modal>` oder `useFormModal()` ersetzen
|
||||
- CSS-Module: `Admin.module.css`, `TrusteeViews.module.css`, etc. — modalOverlay-Klassen entfernen
|
||||
|
||||
## Akzeptanzkriterien
|
||||
|
||||
| # | Kriterium | Prio |
|
||||
|---|-----------|------|
|
||||
| 1 | Alle Modale nutzen `<Modal>` als Container | must |
|
||||
| 2 | ESC schliesst jeden Dialog | must |
|
||||
| 3 | Backdrop-Click schliesst (ausser bei unsaved changes) | must |
|
||||
| 4 | Focus-Trap aktiv bei offenem Modal | must |
|
||||
| 5 | `aria-modal="true"` + `role="dialog"` auf jedem Modal | must |
|
||||
| 6 | grep `modalOverlay` = 0 Treffer nach Abschluss | must |
|
||||
| 7 | `npx tsc --noEmit` = 0 Fehler | must |
|
||||
|
||||
## Abschluss
|
||||
|
||||
- [ ] Modal-Komponente erweitert und dokumentiert
|
||||
- [ ] useFormModal Hook erstellt
|
||||
- [ ] Alle Seiten migriert
|
||||
- [ ] CSS-Cleanup (modalOverlay entfernt)
|
||||
- [ ] layout.md oder eigene modal.md Referenz aktualisiert
|
||||
- [ ] CHANGELOG-Eintraege
|
||||
- [ ] Dieses Dokument -> 4-done/ verschoben
|
||||
|
|
@ -14,6 +14,32 @@ Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler.
|
|||
|
||||
## 2026-06-10
|
||||
|
||||
- 2026-06-10 | fix | ui-nyla | **ViewStack Back-Bug + Hub-Filter in URL**: ViewStack loescht beim Zurueck nicht mehr pauschal `tab` (brach Back bei in LayoutTabs verschachtelten ViewStacks); WorkflowAutomationHubPage haelt Kontext-/Mandantenfilter jetzt in URL (`?context=`) statt `useState`. (Aus Plan-Review.)
|
||||
- 2026-06-10 | docs | wiki | **Layout-Plan Opus-Review-Korrekturen**: 2. Review (Opus 4.8). B1: StackLayout-Variant-Regel fuer tabbed Seiten (Card-Tabs -> `scroll`, nicht `table`) + explizite Variant-Pflicht. W1: L10 Filter-localStorage-Key MUSS Scope (mandate/instance) enthalten (Tenant-Leakage). W2: useDocumentTitle sichtbarkeits-gated (Keep-Alive). W3: L7 Detail-Breadcrumb in ViewStack statt FeatureLayout (Hub ist Top-Level). W4: tote Billing-Seiten aus 5f entfernt. W5: 5-pre-Freeze nur aeussere Struktur. W6: eingebettete Subkomponenten (Pek, RedmineTicketEditor, BillingNav) als 'kein eigenes StackLayout' markiert. N1: Gold-Standard-Header-Kommentar aktualisiert. N5: chatworkflow-PlaceholderViews -> Dead-Code.
|
||||
- 2026-06-10 | docs | wiki | **Layout-Plan Review-Korrekturen**: Plan-Review per Subagent. Phasen ergaenzt (5-pre generische Infra L2/L7/L8/L10/L11 + Keep-Alive-Remeasure als GATE; 6b PanelLayout vor Split-Seiten; 4c als GATE), Doku-Drift gefixt (LayoutTabs `lazy`/`preserveSearchParams`/`syncUrl`-Defaults in layout.md an Code; L9 korrigiert), Dead-Code-Verifikation (RealEstate Dashboard/Parcels/Projects, CommcoachDossier, TrusteePositionDocuments, Billing Dashboard/Transactions/UserView, SolutionsView), Chatworkflow-Views nachgetragen, StackLayout-Variant-Regel + Referenzseiten in regions.md, Subagent-Hartregeln (i18n, Modals nicht anfassen, Dead-Code skip), grep-Kriterium um `adminPage` ergaenzt, Checklisten-Nummerierung korrigiert.
|
||||
- 2026-06-10 | refactor | ui-nyla | **Tab-`subtitle`-Hack entfernt**: ungenutztes `subtitle` aus `LayoutTabItem` (Typ + Rendering + `.tabSubtitle`/`.tabContent` CSS) entfernt. In TrusteeDataTablesView den "Nur lesen"-Subtitle-Hack und das nur dafuer genutzte `readOnly`-Feld aus `TabDef` entfernt; Tabs zeigen jetzt nur den Tabellennamen (Read-only-Schutz bleibt in den Wrappern). Doku layout.md angepasst.
|
||||
- 2026-06-10 | refactor | ui-nyla | **Ungenutztes Tab-`actions`-Feld entfernt (L12)**: `actions` aus `LayoutTabItem` (types.ts), Rendering in LayoutTabs.tsx und `.tabActions` CSS entfernt — war nirgends verwendet.
|
||||
- 2026-06-10 | docs | wiki | **Logik-Fragen L1-L12 entschieden**: L1-L11 entschieden und in Migrations-Checklisten integriert (Loading-States pro Seite, Scroll-Restoration, PanelLayout in 6b, i18n-Pflicht, Token-Pflicht, ARIA/Breadcrumb/ViewStack-Toast/lazy generisch, Filter-/document.title-Persistenz). Nur L12 (Tab-Actions) offen. TeamsbotSessionView + RedmineBrowserView als NEU zu registrierende Keep-Alive-Seiten markiert. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | docs | wiki | **Keep-Alive + Offene Logik-Fragen im Layout-Plan**: Keep-Alive-Markierung pro Seite/Tab in layout-regions.md (WorkspacePage, CommcoachSession, AdminLanguages, AdminDatabaseHealth, WF-Editor-Tab); Keep-Alive-Checkliste in layout.md; 12 offene Logik-Fragen (L1-L12: Loading-States, Scroll-Restoration, PanelLayout, i18n, Dark-Theme, ARIA, Breadcrumb, ViewStack-Toast, lazy/Keep-Alive, Filter-Persistenz, document.title, Action-Lift) in layout-foundation.md dokumentiert.
|
||||
- 2026-06-10 | docs | wiki | **Layout-System Referenz erstellt**: `b-reference/ui-nyla/layout.md` — Scroll-Vertrag, Panel-Varianten (card/table/dashboard/toolbar/editor/wizard), StackLayout, LayoutTabs, ViewStack, Seiten-Aufbau-Muster, Anti-Patterns, Migrations-Checkliste. TOPICS.md aktualisiert.
|
||||
- 2026-06-10 | feat | ui-nyla | **Panel variant-Prop**: Panel-Komponente um `variant` (card/table/dashboard/toolbar/editor/wizard) und `collapseKey` (localStorage-Persistenz) erweitert. CSS-Aenderungen pro Variant wirken systemweit ueber `[data-variant]`.
|
||||
- 2026-06-10 | docs | wiki | **Modal-Konsolidierungsplan erstellt**: `c-work/1-plan/2026-06-modal-consolidation.md` — Analyse aller 3 Modal-Patterns, 5-Stufen-Migrationsplan, Akzeptanzkriterien.
|
||||
- 2026-06-10 | docs | wiki | **Layout Region-Zuordnung**: `c-work/1-plan/2026-06-layout-regions.md` — Explizite Panel-Variant-Zuordnung fuer alle 98 Seiten.
|
||||
- 2026-06-10 | fix | ui-nyla | **RunsTab workflowIdLabel Fix**: `displayField: 'workflowLabel'` auf `'workflowIdLabel'` korrigiert (FK-Resolver-Konvention `{field}Label`). Workflow-Name wird jetzt in Durchlaeufe-Tabelle korrekt angezeigt.
|
||||
- 2026-06-10 | fix | platform-core | **Template-Copy mandantuebergreifend**: `copyTemplateToUser` und `shareTemplate` luden Template via `getWorkflow()` (mandate-scoped) statt `db.getRecord()`. Templates aus anderen Mandanten/Scopes (system, mandate) konnten nicht kopiert werden.
|
||||
- 2026-06-10 | feat | platform-core | **Editor Chat Messages Stub-Route**: `GET /{workflowId}/chat/messages` Endpoint angelegt (gibt `{"messages": []}` zurueck). Behebt 405 Method Not Allowed beim Oeffnen des Workflow-Editors.
|
||||
- 2026-06-10 | docs | wiki | **Migrations-Checkliste fuer UI-Seitenrefactoring**: 7 Kategorien (Daten/API, FK-Labels, FormGeneratorTable, RBAC, fehlende Routen, Layout, Persistenz) basierend auf allen Issues aus Phase 4a/4b. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | fix | platform-core | **CRITICAL Mandantenisolation: isPlatformAdmin Bypass entfernt**: `_scopedWorkflowFilter`, `_scopedRunFilter`, `_getMetrics`, `_listTasks` gaben bei `isPlatformAdmin=True` keinen Filter zurueck (fail-open → alle Mandanten sichtbar). Jetzt: Lesezugriffe IMMER per Mandatsmitgliedschaft gefiltert. isPlatformAdmin nur fuer erhöhte Schreibrechte.
|
||||
- 2026-06-10 | fix | platform-core | **CRITICAL fail-open Fixes**: Templates list/copy/share mandateId validiert; getRecentCompletedRuns full-table-scan durch wfId-Filter ersetzt; Workspace listFeatureDataSources leerer Filter abgesichert (kein mandateId → leeres Ergebnis statt alle FDS).
|
||||
- 2026-06-10 | fix | platform-core | **TODO: Billing + RBAC roles mandateId IDOR**: `routeBilling.py` (scope=mandate + mandateId param) und `routeAdminRbacRules.py` (list_roles mandateId) pruefen mandateId nicht gegen User-Mitgliedschaft. Separater Fix noetig.
|
||||
- 2026-06-10 | fix | ui-nyla | **Workflow-Automation Metriken**: Runs direkt per Mandate-Scope statt indirekt ueber Workflow-IDs gezaehlt; mandateId an Metrics-API gesendet; Tabs laden bei Mandant-Wechsel neu.
|
||||
- 2026-06-10 | feat | ui-nyla | **StackLayout.Header collapsible**: Seitenkopf per Klick/Keyboard ein- und ausklappbar (Chevron, ARIA, optional localStorage via `collapseKey`). Trustee Daten-Tabellen + Workflow-Automation Hub nutzen es. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | refactor | ui-nyla | **WorkflowAutomationHubPage migriert (Phase 4b)**: `UiComponents/Tabs` + manuelles State-Management ersetzt durch StackLayout + LayoutTabs (URL-Sync, aliasMap) + ViewStack (runId→Detail statt Detail-als-Tab). `detail`-Tab eliminiert, Run-Detail lebt jetzt als ViewStack-View in Runs. URL ist Source-of-Truth (kein `activeTab`/`selectedRunId` State mehr). (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | feat | ui-nyla | **SolutionsView MVP (Phase 3)**: Skeleton-Komponente `SolutionsView` als erster Konsument der Layout-Primitive. ViewStack (list/catalog/detail) + LayoutTabs (Einstellungen/Testlauf/Laeufe/Ausgabe) + StackLayout. `settingsSchemaToFormAttributes()` Bruecke fuer FormGeneratorForm. In FeatureView als `trustee.solutions` registriert. Backend-Anbindung pending. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | refactor | ui-nyla | **TrusteeDataTablesView migriert (Phase 4a)**: `adminPage`/`adminPageFill` + inline Tab-Buttons ersetzt durch StackLayout + LayoutTabs. 13 Tabs mit 4 Gruppen, URL-Sync, Lazy-Mount, ARIA. ~100 Zeilen inline Styles eliminiert. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | feat | ui-nyla | **Layout-Primitive (Phase 2)**: 5 neue Komponenten in `components/Layout/`: `StackLayout` (compound, Header/Toolbar/Tabs/Body/Footer, 4 Varianten, scrollMode-Integration), `LayoutTabs` (ARIA, URL-Sync, Alias-Map, Lazy-Mount, Grouped), `ViewStack` (Master→Detail via URL-Entity-Vertrag, Back-Navigation), `Panel` (collapsible, ARIA), `persistence` (pluggable localStorage-Adapter). Barrel-Export via `index.ts`. (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | refactor | ui-nyla | **Feature-Chrome-Budget (Phase 1)**: Doppeltes Padding (`featureContent` 1.5rem + `viewContent` 1.5rem) auf einen Owner (`viewContent`) reduziert. Breadcrumb auf Mobile kondensiert (Mandatsname ausgeblendet, kompaktere Abstände). (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | feat | ui-nyla | **Layout scrollMode-Spike (Phase 0)**: `useScrollMode` Hook + `data-scroll-mode` Attribut auf `<html>`. Auf Mobile/kurzem Viewport (`<=1024px` oder `<=500px` Hoehe) wechselt die gesamte Layout-Kette (MainLayout, FeatureLayout, FeatureView, Admin, FormGeneratorTable) von bounded (overflow:hidden, interner Scroll) zu document (overflow:visible, Header scrollt weg). (c-work: 1-plan/2026-06-layout-foundation.md)
|
||||
- 2026-06-10 | fix | infra | **UI-int Downtime behoben**: nginx auf `porta-int-ui-nyla` crashte wegen DNS-Fehler waehrend `unattended-upgrades` (systemd-networkd Restart + nginx Restart gleichzeitig → `host not found in upstream`). Fix: nginx neugestartet, `needrestart` auf beiden UI-VMs (int + main) auf `'l'` (list-only) konfiguriert — Sicherheitspatches installieren sich weiterhin, Services werden nicht mehr automatisch neugestartet.
|
||||
- 2026-06-10 | chore | platform-core | **poweron-center.net entfernt**: CORS-Regex, env-Dateien und Auth-Kommentar bereinigt — nur noch poweron.swiss.
|
||||
- 2026-06-10 | test | platform-core | **Demo-Tests bereinigt**: 7 Testdateien geloescht die nur DB-Seed-Daten verifizierten (keine Code-Logik). Verbleibend: `test_demo_api.py` (Code-Discovery + Auth) und `test_demo_data_files.py` (Repo-Struktur).
|
||||
|
|
|
|||
Loading…
Reference in a new issue