This commit is contained in:
michael committed 2026-09-23 08:33:48 +00:00
1 parent 008bc8d09c
commit 9107296900
3 files changed
+16 -14

No files matched your search

+3 -7
View File
@@ -1696,7 +1696,7 @@ function DayControlWidget({ stats, projects, todos, onNavigate }: WidgetContentP
);
const todayTickets = stableSort(stats.todayTickets, (left, right) => compareText(left.ticket_number, right.ticket_number));
const todayOpenRatings = stableSort(stats.todayOpenRatings, (left, right) => compareOptionalDate(left.started_at, right.started_at, "asc") || compareText(left.ticket_number, right.ticket_number));
const teamspaceReviewTickets = todayTickets.filter((ticket) => ticket.open_count === 0 && teamspaceDeltaMinutes(ticket) !== 0);
const teamspaceReviewTickets = todayTickets.filter((ticket) => ticket.open_count === 0 && teamspaceDeltaMinutes(ticket) > 0);
const budgetAttention = stableSort(
projects.filter((project) => {
const percent = projectConsumptionPercent(project);
@@ -1891,11 +1891,7 @@ function dayControlTodaySessionReason(ticket: PeriodOverview["tickets"][number])
return `Teamspace nachtragen: ${formatMinutes(deltaMinutes)} fehlen.`;
}
if (deltaMinutes < 0) {
return `Teamspace prüfen: ${formatMinutes(Math.abs(deltaMinutes))} zu viel erfasst.`;
}
if (ticket.total_minutes > 0) {
if (ticket.total_minutes > 0 && deltaMinutes === 0) {
return `Teamspace ok: ${formatMinutes(crmMinutes)} erfasst.`;
}
@@ -1903,7 +1899,7 @@ function dayControlTodaySessionReason(ticket: PeriodOverview["tickets"][number])
return `Nicht abrechenbar gesetzt: Zammad-Dokumentation kontrollieren.`;
}
return "Heute erfasst: Bewertung kontrollieren.";
return ticket.total_minutes > 0 ? "Abgerechnet gesetzt." : "Heute erfasst: Bewertung kontrollieren.";
}
function teamspaceDeltaMinutes(ticket: PeriodOverview["tickets"][number]) {
+10 -4
View File
@@ -157,7 +157,7 @@ function CrmDayItem({
);
}
function TeamspaceDayItem({ item }: { item: StatisticsTeamspaceDay }) {
function TeamspaceDayItem({ item, onNavigate }: { item: StatisticsTeamspaceDay; onNavigate: (to: string) => void }) {
return (
<div className="grid gap-3 rounded-md border bg-background px-3 py-2 lg:grid-cols-[minmax(8rem,0.75fr)_minmax(0,1.65fr)_minmax(8rem,0.6fr)] lg:items-center">
<div className="flex flex-wrap items-center gap-2">
@@ -165,14 +165,20 @@ function TeamspaceDayItem({ item }: { item: StatisticsTeamspaceDay }) {
</div>
<div className="min-w-0 space-y-1">
<div className="flex min-w-0 flex-wrap items-center gap-2">
<span className="font-medium">{item.ticket_number}</span>
<button
type="button"
className="font-medium underline-offset-4 hover:underline"
onClick={() => onNavigate(`/tickets/${item.ticket_id}?month=${item.day.slice(0, 7)}`)}
>
{item.ticket_number}
</button>
<CopyTicketButton ticketNumber={item.ticket_number} />
{item.project_teamspace_project ? <Badge variant="secondary">{item.project_teamspace_project}</Badge> : null}
</div>
<p className="truncate text-sm text-muted-foreground">{item.organization_name}</p>
</div>
<div className="text-sm">
<span className={`font-semibold ${teamspaceTextClass}`}>Teamspace {formatMinutes(item.crm_billed_minutes)}</span>
<Badge variant="success">{formatMinutes(item.crm_billed_minutes)}</Badge>
</div>
</div>
);
@@ -469,7 +475,7 @@ export function MonthlyClosePage({ onNavigate }: MonthlyClosePageProps) {
{teamspaceDays.length > 0 ? (
<div className="max-h-[28rem] space-y-2 overflow-y-auto pr-1">
{teamspaceDays.map((item) => (
<TeamspaceDayItem key={`${item.ticket_id}-${item.day}`} item={item} />
<TeamspaceDayItem key={`${item.ticket_id}-${item.day}`} item={item} onNavigate={onNavigate} />
))}
</div>
) : (
+3 -3
View File
@@ -1723,7 +1723,7 @@ export function TicketDetailPage({ periodType, period, ticketId, onNavigate, onO
return (
<div key={session.id} className="ml-3 rounded-md border bg-card/40 sm:ml-6">
<div className="grid gap-2 p-2 lg:grid-cols-[220px_100px_minmax(260px,auto)_auto] lg:items-center">
<div className="grid gap-2 p-2 lg:grid-cols-[220px_minmax(0,150px)_minmax(260px,1fr)_auto] lg:items-center">
<button
type="button"
className="flex min-w-0 items-center gap-2 rounded-md text-left text-sm text-muted-foreground hover:cursor-pointer hover:text-foreground focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
@@ -1735,12 +1735,12 @@ export function TicketDetailPage({ periodType, period, ticketId, onNavigate, onO
{formatTimeRange(session.started_at, session.ended_at)}
</span>
</button>
<div className="flex flex-wrap gap-1">
<div className="flex min-w-0 flex-col items-start gap-1">
<Badge variant="outline" className="w-fit">{formatMinutes(session.rounded_minutes)}</Badge>
{session.recurring_billing_id ? <Badge variant="secondary">fix</Badge> : null}
{requiresProjectTeamspaceEntry ? (
session.project_teamspace_entry_id ? (
<Badge variant="info">{session.project_teamspace_project || "Teamspace"}</Badge>
<Badge variant="info" className="max-w-full justify-start truncate">{session.project_teamspace_project || "Teamspace"}</Badge>
) : (
<Badge variant="warning">ohne Teamspace</Badge>
)