feat: add inbox auto-advance setting

This commit is contained in:
Brian Lee
2026-04-24 15:04:08 +09:00
parent 33d7404d6c
commit 05156ca793
10 changed files with 132 additions and 5 deletions

View File

@@ -8,6 +8,7 @@ const emptySettings: Settings = {
autogit_enabled: null,
autogit_idle_threshold_seconds: null,
autogit_inactive_threshold_seconds: null,
auto_advance_inbox_after_organize: null,
telemetry_consent: null,
crash_reporting_enabled: null,
analytics_enabled: null,
@@ -138,6 +139,13 @@ describe('SettingsPanel', () => {
expect(screen.getByRole('switch', { name: 'Organize notes explicitly' })).toHaveAttribute('aria-checked', 'true')
})
it('defaults auto-advance to the next inbox item to off', () => {
render(
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
)
expect(screen.getByRole('switch', { name: 'Auto-advance to next Inbox item' })).toHaveAttribute('aria-checked', 'false')
})
it('defaults the initial H1 auto-rename switch to on', () => {
render(
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
@@ -220,6 +228,19 @@ describe('SettingsPanel', () => {
expect(onSaveExplicitOrganization).toHaveBeenCalledWith(false)
})
it('saves the auto-advance inbox preference when toggled on', () => {
render(
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
)
fireEvent.click(screen.getByRole('switch', { name: 'Auto-advance to next Inbox item' }))
fireEvent.click(screen.getByTestId('settings-save'))
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({
auto_advance_inbox_after_organize: true,
}))
})
it('calls onClose when Cancel is clicked', () => {
render(
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />

View File

@@ -47,6 +47,7 @@ interface SettingsDraft {
autoGitEnabled: boolean
autoGitIdleThresholdSeconds: number
autoGitInactiveThresholdSeconds: number
autoAdvanceInboxAfterOrganize: boolean
defaultAiAgent: AiAgentId
releaseChannel: ReleaseChannel
initialH1AutoRename: boolean
@@ -65,6 +66,8 @@ interface SettingsBodyProps {
setAutoGitIdleThresholdSeconds: (value: number) => void
autoGitInactiveThresholdSeconds: number
setAutoGitInactiveThresholdSeconds: (value: number) => void
autoAdvanceInboxAfterOrganize: boolean
setAutoAdvanceInboxAfterOrganize: (value: boolean) => void
aiAgentsStatus: AiAgentsStatus
defaultAiAgent: AiAgentId
setDefaultAiAgent: (value: AiAgentId) => void
@@ -103,6 +106,7 @@ function createSettingsDraft(
settings.autogit_inactive_threshold_seconds,
DEFAULT_AUTOGIT_INACTIVE_THRESHOLD_SECONDS,
),
autoAdvanceInboxAfterOrganize: settings.auto_advance_inbox_after_organize ?? false,
defaultAiAgent: resolveDefaultAiAgent(settings.default_ai_agent),
releaseChannel: normalizeReleaseChannel(settings.release_channel),
initialH1AutoRename: settings.initial_h1_auto_rename_enabled ?? true,
@@ -131,6 +135,7 @@ function buildSettingsFromDraft(settings: Settings, draft: SettingsDraft): Setti
autogit_enabled: draft.autoGitEnabled,
autogit_idle_threshold_seconds: draft.autoGitIdleThresholdSeconds,
autogit_inactive_threshold_seconds: draft.autoGitInactiveThresholdSeconds,
auto_advance_inbox_after_organize: draft.autoAdvanceInboxAfterOrganize,
telemetry_consent: resolveTelemetryConsent(settings, draft),
crash_reporting_enabled: draft.crashReporting,
analytics_enabled: draft.analytics,
@@ -267,6 +272,8 @@ function SettingsPanelInner({
setAutoGitIdleThresholdSeconds={(value) => updateDraft('autoGitIdleThresholdSeconds', value)}
autoGitInactiveThresholdSeconds={draft.autoGitInactiveThresholdSeconds}
setAutoGitInactiveThresholdSeconds={(value) => updateDraft('autoGitInactiveThresholdSeconds', value)}
autoAdvanceInboxAfterOrganize={draft.autoAdvanceInboxAfterOrganize}
setAutoAdvanceInboxAfterOrganize={(value) => updateDraft('autoAdvanceInboxAfterOrganize', value)}
aiAgentsStatus={aiAgentsStatus}
defaultAiAgent={draft.defaultAiAgent}
setDefaultAiAgent={(value) => updateDraft('defaultAiAgent', value)}
@@ -317,6 +324,8 @@ function SettingsBody({
setAutoGitIdleThresholdSeconds,
autoGitInactiveThresholdSeconds,
setAutoGitInactiveThresholdSeconds,
autoAdvanceInboxAfterOrganize,
setAutoAdvanceInboxAfterOrganize,
aiAgentsStatus,
defaultAiAgent,
setDefaultAiAgent,
@@ -373,6 +382,8 @@ function SettingsBody({
<OrganizationWorkflowSection
checked={explicitOrganization}
onChange={setExplicitOrganization}
autoAdvanceInboxAfterOrganize={autoAdvanceInboxAfterOrganize}
onChangeAutoAdvanceInboxAfterOrganize={setAutoAdvanceInboxAfterOrganize}
/>
</SettingsSection>
@@ -707,15 +718,19 @@ function LabeledNumberInput({
function OrganizationWorkflowSection({
checked,
onChange,
autoAdvanceInboxAfterOrganize,
onChangeAutoAdvanceInboxAfterOrganize,
}: {
checked: boolean
onChange: (value: boolean) => void
autoAdvanceInboxAfterOrganize: boolean
onChangeAutoAdvanceInboxAfterOrganize: (value: boolean) => void
}) {
return (
<>
<SectionHeading
title="Workflow"
description="Choose whether Tolaria shows the Inbox workflow and the organized toggle."
description="Choose whether Tolaria shows the Inbox workflow, plus how it moves through items while you triage them."
/>
<SettingsSwitchRow
@@ -725,6 +740,14 @@ function OrganizationWorkflowSection({
onChange={onChange}
testId="settings-explicit-organization"
/>
<SettingsSwitchRow
label="Auto-advance to next Inbox item"
description="When enabled, marking an Inbox note as organized immediately opens the next visible Inbox note."
checked={autoAdvanceInboxAfterOrganize}
onChange={onChangeAutoAdvanceInboxAfterOrganize}
testId="settings-auto-advance-inbox-after-organize"
/>
</>
)
}