feat: Gespiegelte Belegung in der Wochenansicht zeigen
Sie zaehlt gegen die Tageskapazitaet wie jeder fremde Termin, traegt aber keinen Betreff und ist gestreift gezeichnet — damit niemand darin einen Termin vermutet, dem der Titel fehlt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1281c3ea96
commit
0d0f8503cc
@@ -187,6 +187,7 @@ export default async function WocheSeite({
|
|||||||
ganztaegig: t.ganztaegig,
|
ganztaegig: t.ganztaegig,
|
||||||
frei: t.zeigtAls === 'FREI',
|
frei: t.zeigtAls === 'FREI',
|
||||||
kalenderName: t.kalenderName,
|
kalenderName: t.kalenderName,
|
||||||
|
gespiegelt: t.gespiegelt,
|
||||||
}))}
|
}))}
|
||||||
aufgaben={aufgaben.map((a) => ({
|
aufgaben={aufgaben.map((a) => ({
|
||||||
id: a.id,
|
id: a.id,
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ export type RasterTermin = {
|
|||||||
ganztaegig: boolean
|
ganztaegig: boolean
|
||||||
frei: boolean
|
frei: boolean
|
||||||
kalenderName: string
|
kalenderName: string
|
||||||
|
/** Aus der anderen Instanz gespiegelt: belegt, aber ohne Betreff. */
|
||||||
|
gespiegelt?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RasterSpalte = {
|
export type RasterSpalte = {
|
||||||
@@ -321,6 +323,11 @@ export function Wochenraster({
|
|||||||
eintrag.frei
|
eintrag.frei
|
||||||
? 'bg-gedaempft/60 text-gedaempft-vordergrund'
|
? 'bg-gedaempft/60 text-gedaempft-vordergrund'
|
||||||
: 'bg-gedaempft text-gedaempft-vordergrund',
|
: 'bg-gedaempft text-gedaempft-vordergrund',
|
||||||
|
// Gespiegeltes gehört sichtbar in eine eigene
|
||||||
|
// Klasse: gestreift, damit niemand darin einen
|
||||||
|
// Termin mit fehlendem Betreff vermutet.
|
||||||
|
eintrag.gespiegelt &&
|
||||||
|
'border-rand border border-dashed bg-[repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_oklch,currentColor_12%,transparent)_4px,color-mix(in_oklch,currentColor_12%,transparent)_8px)]',
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
top: lage.oben,
|
top: lage.oben,
|
||||||
@@ -328,10 +335,16 @@ export function Wochenraster({
|
|||||||
left: `${(spur / spuren) * 100}%`,
|
left: `${(spur / spuren) * 100}%`,
|
||||||
width: `${100 / spuren}%`,
|
width: `${100 / spuren}%`,
|
||||||
}}
|
}}
|
||||||
title={`${eintrag.betreff ?? 'Termin'} · ${eintrag.kalenderName}`}
|
title={
|
||||||
|
eintrag.gespiegelt
|
||||||
|
? 'Dienstlich belegt – gespiegelt aus der anderen Instanz'
|
||||||
|
: `${eintrag.betreff ?? 'Termin'} · ${eintrag.kalenderName}`
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<span className="line-clamp-2">
|
<span className="line-clamp-2">
|
||||||
{eintrag.betreff ?? 'Termin'}
|
{eintrag.gespiegelt
|
||||||
|
? 'Dienstlich belegt'
|
||||||
|
: (eintrag.betreff ?? 'Termin')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ export type WochenTermin = {
|
|||||||
ganztaegig: boolean
|
ganztaegig: boolean
|
||||||
zeigtAls: ZeigtAls
|
zeigtAls: ZeigtAls
|
||||||
kalenderName: string
|
kalenderName: string
|
||||||
|
/**
|
||||||
|
* Kommt aus der anderen Instanz und trägt darum keinen Betreff.
|
||||||
|
*
|
||||||
|
* Für die Ansicht ist so eine Belegung ein fremder Termin wie jeder andere:
|
||||||
|
* Sie blockiert Zeit und lässt sich hier nicht verschieben.
|
||||||
|
*/
|
||||||
|
gespiegelt: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WocheDaten = {
|
export type WocheDaten = {
|
||||||
@@ -55,7 +62,7 @@ export async function wocheLaden(
|
|||||||
): Promise<WocheDaten> {
|
): Promise<WocheDaten> {
|
||||||
const fenster = wochenFenster(zeitpunkt)
|
const fenster = wochenFenster(zeitpunkt)
|
||||||
|
|
||||||
const [zeitbloecke, termine] = await Promise.all([
|
const [zeitbloecke, termine, belegungen] = await Promise.all([
|
||||||
db.zeitblock.findMany({
|
db.zeitblock.findMany({
|
||||||
where: {
|
where: {
|
||||||
kalenderkonto: { benutzerId },
|
kalenderkonto: { benutzerId },
|
||||||
@@ -97,6 +104,11 @@ export async function wocheLaden(
|
|||||||
kalenderkonto: { select: { anzeigename: true } },
|
kalenderkonto: { select: { anzeigename: true } },
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
db.spiegelbelegung.findMany({
|
||||||
|
where: { beginn: { lt: fenster.bis }, ende: { gt: fenster.von } },
|
||||||
|
orderBy: { beginn: 'asc' },
|
||||||
|
select: { id: true, beginn: true, ende: true },
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
// Ein Zeitblock steht auch im Kalender und damit im Spiegel. Er würde sonst
|
// Ein Zeitblock steht auch im Kalender und damit im Spiegel. Er würde sonst
|
||||||
@@ -118,7 +130,8 @@ export async function wocheLaden(
|
|||||||
letzterFehler: z.letzterFehler,
|
letzterFehler: z.letzterFehler,
|
||||||
offen: z.extId === null,
|
offen: z.extId === null,
|
||||||
})),
|
})),
|
||||||
termine: termine
|
termine: [
|
||||||
|
...termine
|
||||||
.filter((t) => !eigeneExtIds.has(t.extId))
|
.filter((t) => !eigeneExtIds.has(t.extId))
|
||||||
.map((t) => ({
|
.map((t) => ({
|
||||||
id: t.id,
|
id: t.id,
|
||||||
@@ -128,7 +141,20 @@ export async function wocheLaden(
|
|||||||
ganztaegig: t.ganztaegig,
|
ganztaegig: t.ganztaegig,
|
||||||
zeigtAls: t.zeigtAls,
|
zeigtAls: t.zeigtAls,
|
||||||
kalenderName: t.kalenderkonto.anzeigename,
|
kalenderName: t.kalenderkonto.anzeigename,
|
||||||
|
gespiegelt: false,
|
||||||
})),
|
})),
|
||||||
|
...belegungen.map((b) => ({
|
||||||
|
id: b.id,
|
||||||
|
beginn: b.beginn,
|
||||||
|
ende: b.ende,
|
||||||
|
// Kein Betreff: Die andere Instanz schickt bewusst keinen.
|
||||||
|
betreff: null,
|
||||||
|
ganztaegig: false,
|
||||||
|
zeigtAls: 'GEBUCHT' as const,
|
||||||
|
kalenderName: 'Dienstlich',
|
||||||
|
gespiegelt: true,
|
||||||
|
})),
|
||||||
|
].sort((a, b) => a.beginn.getTime() - b.beginn.getTime()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user