fix(reports): Buchungsliste im Dialog nicht mehr rechts abschneiden
Der Dialog war 1152 Punkte breit, die Tabelle brauchte mehr - "Billable Zeit" und "Non-billable Zeit" lagen ausserhalb und waren nur durch seitliches Scrollen zu erreichen, was niemand sieht. - Neue Dialogbreite 3xl: bis 1600 Punkte, hoechstens 95 % des Fensters. - Die Tabelle liegt jetzt auf festen Spaltenbreiten (table-fixed): Datum, Mitarbeiter und die beiden Zeitspalten bekommen ihre Breite, Kunde und Projekt einen Anteil, den Rest nimmt der Task. - Lange Kunden-, Projekt- und Tasknamen samt Notiz brechen um statt abgeschnitten zu werden; die Zahlen brechen nie. Geprueft bei 1920, 1440 und 1280 Punkten: Tabelle passt ohne Querscrollen, die letzte Spalte liegt im Dialog. Auf dem Handy scrollt die Tabelle wie vorher innerhalb des Dialogs, die Seite selbst nicht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7e7188d476
commit
994f39daff
@@ -70,16 +70,16 @@ export const EntryList: React.FC<{
|
||||
|
||||
return (
|
||||
<div className="scrollbar-slim overflow-x-auto">
|
||||
<table className="w-full min-w-[820px] text-sm">
|
||||
<table className="w-full min-w-[720px] table-fixed text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-ink-200 text-[11px] text-ink-400">
|
||||
{head('entry_date', 'Datum', 'left', 'pl-4')}
|
||||
{showUser && head('user_name', 'Mitarbeiter')}
|
||||
{head('customer_name', 'Kunde')}
|
||||
{head('project_display', 'Projekt')}
|
||||
{head('task_name', 'Task')}
|
||||
{head('billable', 'Billable Zeit', 'right')}
|
||||
{head('non_billable', 'Non-billable Zeit', 'right', 'pr-4')}
|
||||
{head('entry_date', 'Datum', 'left', 'w-[110px] pl-4')}
|
||||
{showUser && head('user_name', 'Mitarbeiter', 'left', 'w-[150px]')}
|
||||
{head('customer_name', 'Kunde', 'left', 'w-[18%]')}
|
||||
{head('project_display', 'Projekt', 'left', 'w-[24%]')}
|
||||
{head('task_name', 'Task', 'left')}
|
||||
{head('billable', 'Billable Zeit', 'right', 'w-[104px]')}
|
||||
{head('non_billable', 'Non-billable Zeit', 'right', 'w-[124px] pr-4')}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -110,30 +110,31 @@ export const EntryList: React.FC<{
|
||||
</td>
|
||||
{showUser && (
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="flex items-start gap-2">
|
||||
<Avatar id={e.user_id} name={e.user_name} avatar={e.user_avatar} size={22} />
|
||||
<span className="truncate font-semibold text-ink-700">{e.user_name}</span>
|
||||
<span className="break-words font-semibold text-ink-700">{e.user_name}</span>
|
||||
</span>
|
||||
</td>
|
||||
)}
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="flex min-w-0 items-center gap-2">
|
||||
<span className="h-2.5 w-2.5 shrink-0 rounded-full" style={{ background: colorFor(e.customer_id, e.customer_color) }} />
|
||||
<span className="truncate font-semibold text-ink-700">{e.customer_name}</span>
|
||||
<span className="flex min-w-0 items-start gap-2">
|
||||
<span className="mt-1.5 h-2.5 w-2.5 shrink-0 self-start rounded-full" style={{ background: colorFor(e.customer_id, e.customer_color) }} />
|
||||
<span className="break-words font-semibold text-ink-700">{e.customer_name}</span>
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="block truncate font-bold text-ink-900">{e.project_display}</span>
|
||||
<span className="tabular block truncate text-[11px] text-ink-400">{e.project_code}</span>
|
||||
<span className="block break-words font-bold text-ink-900">{e.project_display}</span>
|
||||
<span className="tabular block text-[11px] text-ink-400">{e.project_code}</span>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="block truncate text-ink-700">{e.task_name ?? '–'}</span>
|
||||
{e.note && <span className="block truncate text-[11px] text-ink-400">{e.note}</span>}
|
||||
{/* Tasknamen und Notizen sind teils sehr lang - hier wird umgebrochen statt abgeschnitten. */}
|
||||
<span className="block break-words text-ink-700">{e.task_name ?? '–'}</span>
|
||||
{e.note && <span className="block break-words text-[11px] text-ink-400">{e.note}</span>}
|
||||
</td>
|
||||
<td className={`tabular px-3 py-2.5 text-right align-top font-extrabold ${bill ? 'text-ink-900' : 'text-ink-300'}`}>
|
||||
<td className={`tabular whitespace-nowrap px-3 py-2.5 text-right align-top font-extrabold ${bill ? 'text-ink-900' : 'text-ink-300'}`}>
|
||||
{bill ? formatHours(bill) : '–'}
|
||||
</td>
|
||||
<td className={`tabular py-2.5 pl-3 pr-4 text-right align-top font-extrabold ${non ? 'text-ink-700' : 'text-ink-300'}`}>
|
||||
<td className={`tabular whitespace-nowrap py-2.5 pl-3 pr-4 text-right align-top font-extrabold ${non ? 'text-ink-700' : 'text-ink-300'}`}>
|
||||
{non ? formatHours(non) : '–'}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -280,7 +280,7 @@ const UserEntriesDialog: React.FC<{
|
||||
);
|
||||
return (
|
||||
<Modal
|
||||
size="2xl"
|
||||
size="3xl"
|
||||
onClose={onClose}
|
||||
title={row.name}
|
||||
subtitle={
|
||||
|
||||
@@ -20,10 +20,18 @@ interface ModalProps {
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
||||
size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
||||
}
|
||||
|
||||
const SIZES = { sm: 'sm:max-w-sm', md: 'sm:max-w-lg', lg: 'sm:max-w-2xl', xl: 'sm:max-w-4xl', '2xl': 'sm:max-w-6xl' };
|
||||
const SIZES = {
|
||||
sm: 'sm:max-w-sm',
|
||||
md: 'sm:max-w-lg',
|
||||
lg: 'sm:max-w-2xl',
|
||||
xl: 'sm:max-w-4xl',
|
||||
'2xl': 'sm:max-w-6xl',
|
||||
// Fuer breite Tabellen: nimmt fast das ganze Fenster, hoert aber bei 1600 px auf.
|
||||
'3xl': 'sm:max-w-[min(100rem,95vw)]',
|
||||
};
|
||||
|
||||
/** Offene Dialoge in Oeffnungsreihenfolge - Escape schliesst nur den obersten. */
|
||||
const openModals: symbol[] = [];
|
||||
|
||||
Reference in New Issue
Block a user