int #6

Merged
p.motsch merged 6 commits from int into main 2026-06-12 12:08:34 +00:00
10 changed files with 90 additions and 20 deletions
Showing only changes of commit 27abfde833 - Show all commits

View file

@ -5,6 +5,18 @@
border-radius: 8px;
background: var(--bg-primary, #fff);
overflow: clip;
display: flex;
flex-direction: column;
min-height: 0;
}
/* Card regions in bounded flex hosts (sidebar, PanelLayout pane): body fills and scrolls. */
.panel[data-variant="card"] .body:not(.bodyHidden) {
flex: 1;
min-height: 0;
overflow: auto;
display: flex;
flex-direction: column;
}
/* --- Variant: table — fills available height, bounded scroll --- */
@ -94,11 +106,14 @@
background: var(--bg-secondary, rgba(0, 0, 0, 0.02));
border-bottom: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
min-height: 40px;
position: relative;
}
.headerCollapsible {
cursor: pointer;
user-select: none;
/* Reserve space so action icons never overlap the collapse chevron */
padding-right: 30px;
}
.headerCollapsible:hover {
@ -128,15 +143,20 @@
}
.actions {
flex-shrink: 0;
flex-shrink: 1;
min-width: 0;
display: flex;
align-items: center;
gap: 4px;
margin-left: auto;
}
/* Stable chevron position: fixed at the right edge of the header, same spot
whether collapsed or expanded. Icon swaps (down = open, right = collapsed). */
/* Collapse chevron: always rightmost, above action icons (never covered). */
.chevron {
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
flex-shrink: 0;
display: inline-flex;
align-items: center;
@ -145,6 +165,8 @@
height: 16px;
font-size: 12px;
color: var(--text-tertiary, #888);
z-index: 2;
pointer-events: none;
}
.body {

View file

@ -75,12 +75,12 @@ export const Panel: FC<PanelProps> = ({
<span className={styles.title}>{title}</span>
{subtitle && <span className={styles.subtitle}>{subtitle}</span>}
</div>
{actions && <div className={styles.actions} onClick={(e) => e.stopPropagation()}>{actions}</div>}
{collapsible && (
<span className={styles.chevron} aria-hidden>
{collapsed ? <FaChevronRight /> : <FaChevronDown />}
</span>
)}
{actions && <div className={styles.actions} onClick={(e) => e.stopPropagation()}>{actions}</div>}
</div>
<div className={`${styles.body} ${collapsed ? styles.bodyHidden : ''}`}>
{children}

View file

@ -3,6 +3,8 @@
flex-direction: column;
flex: 1;
min-height: 0;
height: 100%;
overflow: hidden;
gap: 8px;
}
@ -100,6 +102,9 @@
.tree {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
overflow-y: auto;
}
.chatItem {

View file

@ -0,0 +1,22 @@
.sourcesTab {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
height: 100%;
overflow: hidden;
}
.treeHost {
flex: 1;
min-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
}
.empty {
padding: 12px;
font-size: 12px;
color: #888;
}

View file

@ -20,6 +20,7 @@ import { createUdbSourcesProvider } from './UdbSourcesProvider';
import type { UdbBackendNode } from './UdbSourcesProvider';
import { DataSourceSettingsModal } from './DataSourceSettingsModal';
import { useLanguage } from '../../providers/language/LanguageContext';
import styles from './SourcesTab.module.css';
interface SourcesTabProps {
context: UdbContext;
@ -84,15 +85,15 @@ const SourcesTab: React.FC<SourcesTabProps> = ({
if (!instanceId || !provider) {
return (
<div style={{ padding: 12, fontSize: 12, color: '#888' }}>
<div className={styles.empty}>
{t('Keine Workspace-Instanz aktiv.')}
</div>
);
}
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', minHeight: 0 }}>
<div style={{ flex: 1, overflow: 'auto', minHeight: 0 }}>
<div className={styles.sourcesTab}>
<div className={styles.treeHost}>
<FormGeneratorTree
provider={provider}
ownership="own"

View file

@ -41,7 +41,9 @@
.tabContent {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow: hidden;
display: flex;
flex-direction: column;
padding: 8px;
}

View file

@ -394,7 +394,7 @@ export const CommcoachSessionView: React.FC = () => {
collapsible: true,
collapseKey: 'commcoach-session-udb',
content: (
<Panel variant="card" title={t('Datenquellen')} id="commcoach-session-data-sources">
<Panel variant="card" title={t('Datenquellen')} id="commcoach-session-data-sources" fill>
<UnifiedDataBar
context={_udbContext}
activeTab={udbTab}

View file

@ -1006,7 +1006,7 @@ export const TeamsbotSessionView: React.FC = () => {
collapsible: true,
collapseKey: 'teamsbot-session-udb',
content: (
<Panel variant="card" title={t('Datenquellen')} id="teamsbot-session-datasources">
<Panel variant="card" title={t('Datenquellen')} id="teamsbot-session-datasources" fill>
<UnifiedDataBar
context={_udbContext}
activeTab={udbTab}

View file

@ -67,6 +67,19 @@ export const WorkspaceContextSidebar: React.FC<WorkspaceContextSidebarProps> = (
aria-label="Kontext"
>
<div className={styles.contextToolbar}>
{allowCollapse && (
<button
type="button"
className={styles.contextCollapseBtn}
onClick={onToggleCollapsed}
title={isCollapsed ? 'Kontext ausklappen' : 'Kontext einklappen'}
aria-expanded={!isCollapsed}
>
{isCollapsed ? <FaChevronRight aria-hidden /> : <FaChevronLeft aria-hidden />}
</button>
)}
{!isCollapsed && (
<>
<button
type="button"
className={`${styles.contextToolBtn} ${activeTab === 'files' ? styles.contextToolBtnActive : ''}`}
@ -104,16 +117,7 @@ export const WorkspaceContextSidebar: React.FC<WorkspaceContextSidebarProps> = (
<FaEye aria-hidden />
</button>
<span className={styles.contextToolbarGrow} />
{allowCollapse && (
<button
type="button"
className={styles.contextCollapseBtn}
onClick={onToggleCollapsed}
title={isCollapsed ? 'Kontext ausklappen' : 'Kontext einklappen'}
aria-expanded={!isCollapsed}
>
{isCollapsed ? <FaChevronRight aria-hidden /> : <FaChevronLeft aria-hidden />}
</button>
</>
)}
</div>
{!isCollapsed && (

View file

@ -162,6 +162,20 @@
width: 44px;
}
.contextSidebarCollapsed .contextToolbar {
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 6px 4px;
gap: 6px;
border-bottom: none;
}
.contextSidebarCollapsed .contextCollapseBtn {
width: 32px;
height: 32px;
}
/* When hosted inside a PanelLayout pane, the sidebar fills the pane width so
the divider controls its size (instead of the fixed 320px). */
.contextSidebarFill {