The SBB timetable widget is too niche to include by default during
onboarding. Add it back to defaultWidgetConfigs with skip: true so
it won't be placed automatically.
The select, configure, and done phases each had different hardcoded
widths causing a jarring layout shift when transitioning between them.
Unify all three to a single CARD_WIDTH constant.
Allow skipping individual integrations during onboarding without
filling in the form. Adds an optional onSkip prop to NewIntegrationForm
that advances to the next integration or finishes setup.
The multi-select grid initializes its own internal Set on mount, so
returning from the configure phase to the select phase lost all
selections. Accept an initialSelection prop and pass the parent's
selectedKinds to restore state on re-mount.
Modal.extend() is not available at module evaluation time in the
Next.js/Turbopack ESM context, causing a runtime TypeError. Define
the vars resolver as a plain object in createTheme's components key.
- Extract placeWidgetAsync into a standalone function with a
PlaceWidgetContext parameter for clearer state management.
- Fix widget skip logic: use config?.skip instead of !config || config.skip
so integration-specific widgets without an explicit defaultWidgetConfigs
entry are still placed with default 2x2 sizes.
- Add createIntegration mutation for onboarding (no app linking or
search engine creation needed during init).
- Fix nextOnboardingStepAsync call: pass undefined instead of "start"
to advance naturally without resetting to the beginning.
- Add early return when no board is found in setupIntegrations.
- Make onSuccess a required prop on NewIntegrationForm so the consumer
always controls post-creation behavior. Remove internal router.push.
- Add IntegrationNewFormWrapper client component to handle navigation
for the server-rendered manage page.
- Replace IntegrationPickerPage with a simple "back to overview" button
when an invalid integration kind is provided. Delete unused
integration-picker-page.tsx.
- Replace Mantine Stepper with a Progress bar + current integration
avatar/name. The stepper broke layout with 10+ integrations on mobile.
- Remove useEffect for setupIntegrations — call it directly when
advancing past the last integration or clicking skip, avoiding
double-call risks (cf. Cloudflare outage pattern).
- Call router.refresh() after setupIntegrations so the server-rendered
InitFinish component renders properly with login links.
- Remove DB query from init-finish.tsx — redirect to root path instead
of looking up an arbitrary board name.
Hardcoded size: 1200 could overflow on narrow viewports. Add a custom
"xxl" size (75rem) to the Mantine Modal theme via a vars resolver.
Mantine caps modal width at 100vw so it naturally adapts on mobile.
Use "xxl" in item-select, app-select, and integration-select modals.
Both IntegrationMultiSelectGrid and IntegrationSelectGrid had
duplicated logic for building widget-by-integration maps, category
labels, sorting, and filtering. Extract shared code into
integration-grid-shared.ts using objectEntries and IntegrationKind
typing. Use i18n keys for category badges and widget counts instead
of hardcoded strings. Remove useEffect for onSelectionChange in
multi-select grid — call it directly in the toggle callback.
Category labels and widget count badges in the integration grid were
hardcoded English strings. Add proper i18n keys under integration.grid
and integration.category so they can be translated.
- Remove unused timetable skip entry from defaultWidgetConfigs
- Use "seerr" instead of "jellyseerr" in featuredIntegrations
- Add "Support Homarr" OpenCollective link to defaultBookmarkApps