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 (
|
return (
|
||||||
<div className="scrollbar-slim overflow-x-auto">
|
<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>
|
<thead>
|
||||||
<tr className="border-b border-ink-200 text-[11px] text-ink-400">
|
<tr className="border-b border-ink-200 text-[11px] text-ink-400">
|
||||||
{head('entry_date', 'Datum', 'left', 'pl-4')}
|
{head('entry_date', 'Datum', 'left', 'w-[110px] pl-4')}
|
||||||
{showUser && head('user_name', 'Mitarbeiter')}
|
{showUser && head('user_name', 'Mitarbeiter', 'left', 'w-[150px]')}
|
||||||
{head('customer_name', 'Kunde')}
|
{head('customer_name', 'Kunde', 'left', 'w-[18%]')}
|
||||||
{head('project_display', 'Projekt')}
|
{head('project_display', 'Projekt', 'left', 'w-[24%]')}
|
||||||
{head('task_name', 'Task')}
|
{head('task_name', 'Task', 'left')}
|
||||||
{head('billable', 'Billable Zeit', 'right')}
|
{head('billable', 'Billable Zeit', 'right', 'w-[104px]')}
|
||||||
{head('non_billable', 'Non-billable Zeit', 'right', 'pr-4')}
|
{head('non_billable', 'Non-billable Zeit', 'right', 'w-[124px] pr-4')}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -110,30 +110,31 @@ export const EntryList: React.FC<{
|
|||||||
</td>
|
</td>
|
||||||
{showUser && (
|
{showUser && (
|
||||||
<td className="px-3 py-2.5 align-top">
|
<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} />
|
<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>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
)}
|
)}
|
||||||
<td className="px-3 py-2.5 align-top">
|
<td className="px-3 py-2.5 align-top">
|
||||||
<span className="flex min-w-0 items-center gap-2">
|
<span className="flex min-w-0 items-start 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="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="truncate font-semibold text-ink-700">{e.customer_name}</span>
|
<span className="break-words font-semibold text-ink-700">{e.customer_name}</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2.5 align-top">
|
<td className="px-3 py-2.5 align-top">
|
||||||
<span className="block truncate font-bold text-ink-900">{e.project_display}</span>
|
<span className="block break-words 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="tabular block text-[11px] text-ink-400">{e.project_code}</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2.5 align-top">
|
<td className="px-3 py-2.5 align-top">
|
||||||
<span className="block truncate text-ink-700">{e.task_name ?? '–'}</span>
|
{/* Tasknamen und Notizen sind teils sehr lang - hier wird umgebrochen statt abgeschnitten. */}
|
||||||
{e.note && <span className="block truncate text-[11px] text-ink-400">{e.note}</span>}
|
<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>
|
||||||
<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) : '–'}
|
{bill ? formatHours(bill) : '–'}
|
||||||
</td>
|
</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) : '–'}
|
{non ? formatHours(non) : '–'}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ const UserEntriesDialog: React.FC<{
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
size="2xl"
|
size="3xl"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
title={row.name}
|
title={row.name}
|
||||||
subtitle={
|
subtitle={
|
||||||
|
|||||||
@@ -20,10 +20,18 @@ interface ModalProps {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
footer?: 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. */
|
/** Offene Dialoge in Oeffnungsreihenfolge - Escape schliesst nur den obersten. */
|
||||||
const openModals: symbol[] = [];
|
const openModals: symbol[] = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user