Files
webmail/lib/demo/fixtures/tasks.ts
T
Linus Rath 4c0017d0c1 feat: rework the demo around one persona with two accounts and a shared mailbox
The demo user becomes Nora Lindqvist, engineering lead at Meridian Labs,
in the week of a product launch. The fixtures tell one story across mail,
contacts, calendar, tasks and files, and exercise the features the
screenshots and the public demo should show:

- a second, mail-only login (her personal domain) and the shared Support
  mailbox delegated to the work account, so the account switcher, the
  shared section and the merged inbox have real content
- raw headers the way Stalwart writes them: the sender check fails on
  the phishing mail, newsletters carry a one-click unsubscribe, one mail
  asks for a read receipt, and spam scores show in the details
- an iMIP invitation with a served .ics, an event waiting for the answer
  on the calendar, and RSVP patches applied in the demo client
- @mentions as mailto links in a received mail, a verification code
  twelve minutes old, nested folders, named tags on the mail, contact
  groups, a scheduled message and tasks switched on
- every attachment and file backed by real bytes under public/demo,
  generated by `scripts/demo-assets/generate.mjs`; contact photos are
  bundled portraits instead of requests to randomuser.me
- folder counts computed from the mail instead of hand-kept numbers

Demo login seeds the tags, templates and merged-inbox settings once per
device and switches the cross-account gate on for the session; "Reset"
restores them. `bulwark-demo-simulate=off` in localStorage stops the
simulated incoming mail for screenshot runs.
2026-10-18 19:48:11 +02:00

53 lines
2.8 KiB
TypeScript

import type { CalendarTask } from '@/lib/jmap/types';
import { demoDate } from '../demo-utils';
import { CAL } from './calendars';
type Progress = 'needs-action' | 'in-process' | 'completed';
function task(id: string, calendar: string, title: string, due: string, extra: { description?: string; progress?: Progress; priority?: number; allDay?: boolean; alert?: boolean; created?: string } = {}): CalendarTask {
const progress = extra.progress ?? 'needs-action';
return {
id,
calendarIds: { [calendar]: true },
'@type': 'Task',
uid: `${id}@meridianlabs.example`,
title,
description: extra.description ?? '',
due,
start: null,
duration: null,
timeZone: null,
showWithoutTime: extra.allDay ?? true,
progress,
progressUpdated: progress === 'needs-action' ? null : demoDate(0, -3),
priority: extra.priority ?? 0,
privacy: 'public',
keywords: null,
categories: null,
color: null,
created: extra.created ?? demoDate(-5),
updated: demoDate(-1),
recurrenceRules: null,
alerts: extra.alert ? {
'alert-1': { '@type': 'Alert', trigger: { '@type': 'OffsetTrigger', offset: '-PT1H', relativeTo: 'start' }, action: 'display', acknowledged: null, relatedTo: null },
} : null,
relatedTo: null,
} as CalendarTask;
}
export function createDemoCalendarTasks(): CalendarTask[] {
return [
task('demo-task-runbook', CAL.work, 'Rollback runbook: work in Bob\'s comments', demoDate(1, 2), { description: 'Name the dashboard owner in step 3; drop the signing-key question.', progress: 'in-process', priority: 1, allDay: false, alert: true }),
task('demo-task-rsvp', CAL.work, 'RSVP to the go / no-go review', demoDate(0, 4), { priority: 1, allDay: false }),
task('demo-task-quote', CAL.work, 'Quote for Rachel\'s launch post', demoDate(3), { description: 'Two sentences. Not "we are excited".', priority: 5 }),
task('demo-task-canary-list', CAL.work, 'Pick the five canary tenants with Priya', demoDate(4), { description: 'Lumen Logistics is one.' }),
task('demo-task-slides', CAL.work, 'Finish Infra Summit slides', demoDate(8), { progress: 'in-process', priority: 5, created: demoDate(-12) }),
task('demo-task-review-pr', CAL.work, 'Review #1284 (signing key overlap)', demoDate(-1), { progress: 'completed', created: demoDate(-3) }),
task('demo-task-invoice', CAL.work, 'Approve DesignCo invoice 2026-089', demoDate(2), { priority: 9 }),
task('demo-task-mom', CAL.personal, 'Tell Mom which weekend', demoDate(4), { priority: 5 }),
task('demo-task-suit', CAL.personal, 'Pick up the suit from the cleaner', demoDate(-2), { priority: 9 }),
task('demo-task-passport', CAL.personal, 'Check passport is in the travel wallet', demoDate(8), { progress: 'completed' }),
task('demo-task-snacks', CAL.personal, 'Snacks for book club', demoDate(2)),
];
}