mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
a7adef5353
- Admin settings (desktop and phone, self-hosted only): the instance switch,
how mail arrives (IMAP or a signed webhook) with its fields, the address
template, the AI allowance per person and day, a connection test and the
status in counts. Changed fields only are saved; secrets stay masked.
- The review mark of an imported booking takes its mark off: the pill in the
desktop dialog and a row in the phone's transport sheet ('Looks right'),
through the ordinary booking update. Its hint no longer speaks of airports.
- The inbox follows mailInbox:changed and mailInbox:settings, and
?inbox=mail (the 'bookings waiting' notification) opens it.
- mailIngestRepo: the online-only path the views take, answers parsed
against the shared contracts.
- Dropped 'read with AI' and the unused mail-review contract: the server
reads a passing AI failure again on its own.
- mailInbox, mailAdmin and the new reservation, settings and notification
strings in all 28 locales; the pending notice is a plural group.
- The live flight line on the booking cards is one of the card's fields,
full width on the phone; the phone's live card keeps its map to the middle.
- Admin flight and mail cards sit in the left column.
50 lines
2.0 KiB
TypeScript
50 lines
2.0 KiB
TypeScript
/**
|
|
* Labels for the notification matrix, shared by the desktop and phone settings
|
|
* and the admin's defaults for users (#1536), so the three can never name an
|
|
* event differently.
|
|
*/
|
|
|
|
export interface NotificationChannelDescriptor {
|
|
id: string
|
|
source?: 'builtin' | 'plugin'
|
|
labelKey?: string
|
|
label?: string
|
|
settingsPath?: string
|
|
active: boolean
|
|
configured: boolean
|
|
}
|
|
|
|
export const EVENT_LABEL_KEYS: Record<string, string> = {
|
|
trip_invite: 'settings.notifyTripInvite',
|
|
booking_change: 'settings.notifyBookingChange',
|
|
trip_reminder: 'settings.notifyTripReminder',
|
|
todo_due: 'settings.notifyTodoDue',
|
|
vacay_invite: 'settings.notifyVacayInvite',
|
|
vacay_share: 'settings.notifyVacayShare',
|
|
collection_invite: 'settings.notifyCollectionInvite',
|
|
synology_session_cleared: 'settings.notifySynologySessionCleared',
|
|
plugin_notification: 'settings.notifyPluginNotification',
|
|
photos_shared: 'settings.notifyPhotosShared',
|
|
collab_message: 'settings.notifyCollabMessage',
|
|
packing_tagged: 'settings.notifyPackingTagged',
|
|
wanderer_source_hint: 'settings.notifyWandererSourceHint',
|
|
version_available: 'settings.notifyVersionAvailable',
|
|
flight_departed: 'settings.notifyFlightDeparted',
|
|
flight_delayed: 'settings.notifyFlightDelayed',
|
|
flight_landed: 'settings.notifyFlightLanded',
|
|
mail_booking_added: 'settings.notifyMailBookingAdded',
|
|
mail_booking_pending: 'settings.notifyMailBookingPending',
|
|
mail_ingest_paused: 'settings.notifyMailIngestPaused',
|
|
}
|
|
|
|
/** Plugin channels have no i18n; the server sends their display name outright. */
|
|
export function channelLabel(ch: { id: string; labelKey?: string; label?: string }, t: (k: string) => string): string {
|
|
if (ch.labelKey) return t(ch.labelKey) || ch.id
|
|
return ch.label || ch.id
|
|
}
|
|
|
|
/** True when the admin switched this cell off for everyone (#1536). */
|
|
export function isLockedCell(locked: Record<string, string[]> | undefined, eventType: string, channel: string): boolean {
|
|
return !!locked?.[eventType]?.includes(channel)
|
|
}
|