fix(aufgaben): Ideen aus Aufgabenliste und Inbox heraushalten
Der Fehler fiel erst in den aufgenommenen Bildern auf: Ideen standen mitten in der Aufgabenliste, obwohl der ganze Sinn der getrennten Ideenseite ist, dass sie das nicht tun. Ohne Termin hätten sie dort entweder unsichtbar unten gestanden oder mit erfundenem Termin oben. Der Filter kennt jetzt ohneIdeen; ein ausdrücklich gewählter Typ gewinnt, wer nach Ideen filtert, sieht sie also weiterhin. Die Startseite filterte Ideen bisher von Hand nach dem Laden — das erledigt jetzt dieselbe Abfrage wie überall sonst. Ein E2E-Test hält den Fall fest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7c8fe10f35
commit
144457b9f0
@@ -107,6 +107,34 @@ test.describe('Aufgaben', () => {
|
|||||||
await expect(page.locator('li').filter({ hasText: titel })).toHaveCount(0)
|
await expect(page.locator('li').filter({ hasText: titel })).toHaveCount(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('hält Ideen aus der Aufgabenliste heraus', async ({ page }) => {
|
||||||
|
const idee = `${PRAEFIX} Nur eine Idee`
|
||||||
|
const aufgabe = `${PRAEFIX} Eine echte Aufgabe`
|
||||||
|
await db.aufgabe.createMany({
|
||||||
|
data: [
|
||||||
|
{ titel: idee, typ: 'IDEE' },
|
||||||
|
{ titel: aufgabe, typ: 'AUFGABE' },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
await anmelden(page)
|
||||||
|
|
||||||
|
// In der Aufgabenliste hat die Idee nichts zu suchen.
|
||||||
|
await page.goto('/aufgaben')
|
||||||
|
await expect(page.locator('li').filter({ hasText: aufgabe })).toBeVisible()
|
||||||
|
await expect(page.locator('li').filter({ hasText: idee })).toHaveCount(0)
|
||||||
|
|
||||||
|
// Auch nicht in der Inbox, obwohl beide keinen Bereich haben.
|
||||||
|
await page.goto('/inbox')
|
||||||
|
await expect(page.locator('li').filter({ hasText: aufgabe })).toBeVisible()
|
||||||
|
await expect(page.locator('li').filter({ hasText: idee })).toHaveCount(0)
|
||||||
|
|
||||||
|
// Wer ausdrücklich danach filtert, sieht sie sehr wohl.
|
||||||
|
await page.goto('/aufgaben?typ=IDEE')
|
||||||
|
await expect(page.locator('li').filter({ hasText: idee })).toBeVisible()
|
||||||
|
await expect(page.locator('li').filter({ hasText: aufgabe })).toHaveCount(0)
|
||||||
|
})
|
||||||
|
|
||||||
test('filtert nach Bereich und über die Adresszeile', async ({ page }) => {
|
test('filtert nach Bereich und über die Adresszeile', async ({ page }) => {
|
||||||
await anmelden(page)
|
await anmelden(page)
|
||||||
const bereich = await db.bereich.findFirst({
|
const bereich = await db.bereich.findFirst({
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ function filterAus(
|
|||||||
: { nurOffen: true }),
|
: { nurOffen: true }),
|
||||||
...(typ && TYP_WERTE.includes(typ) ? { typ: typ as AufgabenTyp } : {}),
|
...(typ && TYP_WERTE.includes(typ) ? { typ: typ as AufgabenTyp } : {}),
|
||||||
...(einer('suche') ? { suche: einer('suche') } : {}),
|
...(einer('suche') ? { suche: einer('suche') } : {}),
|
||||||
|
// Ideen haben ihre eigene Seite; wer sie hier sehen will, filtert danach.
|
||||||
|
ohneIdeen: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default async function InboxSeite() {
|
|||||||
await verlangeAnmeldung('/inbox')
|
await verlangeAnmeldung('/inbox')
|
||||||
|
|
||||||
const [aufgaben, bereiche, projekte] = await Promise.all([
|
const [aufgaben, bereiche, projekte] = await Promise.all([
|
||||||
aufgabenLaden({ nurInbox: true, nurOffen: true }),
|
aufgabenLaden({ nurInbox: true, nurOffen: true, ohneIdeen: true }),
|
||||||
bereicheLaden(),
|
bereicheLaden(),
|
||||||
projekteZurAuswahlLaden(),
|
projekteZurAuswahlLaden(),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default async function StartSeite() {
|
|||||||
const heute = jetzt()
|
const heute = jetzt()
|
||||||
|
|
||||||
const [alleOffenen, bereiche, projekte, zahlen, bereichsListe] = await Promise.all([
|
const [alleOffenen, bereiche, projekte, zahlen, bereichsListe] = await Promise.all([
|
||||||
aufgabenLaden({ nurOffen: true }, 200),
|
aufgabenLaden({ nurOffen: true, ohneIdeen: true }, 200),
|
||||||
bereicheLaden(),
|
bereicheLaden(),
|
||||||
projekteZurAuswahlLaden(),
|
projekteZurAuswahlLaden(),
|
||||||
zaehlstaende(),
|
zaehlstaende(),
|
||||||
@@ -35,11 +35,9 @@ export default async function StartSeite() {
|
|||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
// Was jetzt zählt: überfällig, heute oder morgen fällig. Ideen bleiben draußen.
|
// Was jetzt zählt: überfällig, heute oder morgen fällig.
|
||||||
const dran = alleOffenen.filter(
|
const dran = alleOffenen.filter(
|
||||||
(a) =>
|
(a) => a.ueberfaellig || a.faelligkeit === 'heute' || a.faelligkeit === 'morgen',
|
||||||
a.typ !== 'IDEE' &&
|
|
||||||
(a.ueberfaellig || a.faelligkeit === 'heute' || a.faelligkeit === 'morgen'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const anrede = benutzer.name?.split(' ')[0] ?? benutzer.email
|
const anrede = benutzer.name?.split(' ')[0] ?? benutzer.email
|
||||||
@@ -109,9 +107,7 @@ export default async function StartSeite() {
|
|||||||
) : (
|
) : (
|
||||||
<ul className="grid gap-4 sm:grid-cols-2">
|
<ul className="grid gap-4 sm:grid-cols-2">
|
||||||
{bereichsListe.map((bereich) => {
|
{bereichsListe.map((bereich) => {
|
||||||
const offeneHier = alleOffenen.filter(
|
const offeneHier = alleOffenen.filter((a) => a.bereich?.id === bereich.id)
|
||||||
(a) => a.bereich?.id === bereich.id && a.typ !== 'IDEE',
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
<li key={bereich.id}>
|
<li key={bereich.id}>
|
||||||
<Card>
|
<Card>
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ export type AufgabenFilter = {
|
|||||||
nurInbox?: boolean | undefined
|
nurInbox?: boolean | undefined
|
||||||
/** Nur was noch Arbeit bedeutet. */
|
/** Nur was noch Arbeit bedeutet. */
|
||||||
nurOffen?: boolean | undefined
|
nurOffen?: boolean | undefined
|
||||||
|
/**
|
||||||
|
* Ideen heraushalten. Sie haben ihre eigene Ansicht und sollen sich nicht
|
||||||
|
* in die Aufgabenliste drängen — sie hätten dort keinen Termin und stünden
|
||||||
|
* entweder unsichtbar unten oder mit erfundenem Termin oben.
|
||||||
|
*/
|
||||||
|
ohneIdeen?: boolean | undefined
|
||||||
/** Freitext über Titel und Notiz. */
|
/** Freitext über Titel und Notiz. */
|
||||||
suche?: string | undefined
|
suche?: string | undefined
|
||||||
}
|
}
|
||||||
@@ -49,7 +55,11 @@ function alsWhere(filter: AufgabenFilter): Prisma.AufgabeWhereInput {
|
|||||||
else if (filter.bereichId) where.bereichId = filter.bereichId
|
else if (filter.bereichId) where.bereichId = filter.bereichId
|
||||||
|
|
||||||
if (filter.projektId) where.projektId = filter.projektId
|
if (filter.projektId) where.projektId = filter.projektId
|
||||||
|
|
||||||
|
// Ein ausdrücklich gewählter Typ gewinnt: wer nach Ideen filtert, will sie
|
||||||
|
// auch sehen.
|
||||||
if (filter.typ) where.typ = filter.typ
|
if (filter.typ) where.typ = filter.typ
|
||||||
|
else if (filter.ohneIdeen) where.typ = { not: 'IDEE' }
|
||||||
|
|
||||||
if (filter.status) where.status = filter.status
|
if (filter.status) where.status = filter.status
|
||||||
else if (filter.nurOffen) where.status = { in: ['OFFEN', 'GEPLANT', 'WARTET'] }
|
else if (filter.nurOffen) where.status = { in: ['OFFEN', 'GEPLANT', 'WARTET'] }
|
||||||
|
|||||||
Reference in New Issue
Block a user