Skip to content

Notification reminder values not saved when editing pre-due/post-due times #232

Description

@stef204

Description

When creating a task with custom reminder times (e.g., 5 minutes before due, 5 minutes after due), the saved notification templates contain incorrect values. The UI input field shows the correct number (e.g., 5), but the database stores the default value (1) instead.

Steps to Reproduce

  1. Create a new task
  2. Add a pre-due reminder
  3. Change the unit dropdown from "day" to "min"
  4. Change the value from 1 to 5 in the number input
  5. Add a post-due reminder and repeat steps 2-4
  6. Save the task
  7. Inspect the task's notification metadata in the database

Expected Behavior

When pressing "Create" or "Save" button, the notification templates should save as:

{
  "templates": [
    {"value": -5, "unit": "m"},
    {"value": 0, "unit": "m"},
    {"value": 5, "unit": "m"}
  ]
}

Actual Behavior

The notification templates save as:

{
  "templates": [
    {"value": -1, "unit": "m"},
    {"value": 0, "unit": "m"},
    {"value": 1, "unit": "m"}
  ]
}

The value 5 is silently discarded and replaced with the default 1.

Visual Evidence

When typing 5 into the number input for either pre-due or post-due reminders, the reminder label continues to display "1 min before due" or "1 min after due" instead of updating to "5 min". The input field and the label are out of sync, and the label's value is what ultimately gets saved.

Technical Details

The issue appears to be in src/components/NotificationTemplate.jsx. The input field stores its value in the draftValues state, but the label (via getDisplayLabel) reads from value.templates. When the user changes the input value and blurs the field, the updated value is not properly propagated to the templates array before save.

Relevant code:

// onChange stores raw input in draftValues
onChange={e => {
  const val = e.target.value
  if (val.includes('-')) return
  setDraftValues(prev => ({ ...prev, [idx]: val }))
}}

// onBlur commits the value
onBlur={e => {
  let val = e.target.value
  const numericVal = Number(val)
  val = numericVal <= 0 ? (hasOnDueElsewhere ? 1 : 0) : numericVal
  handleChange(idx, 'displayValue', val)
  setDraftValues(prev => {
    const next = { ...prev }
    delete next[idx]
    return next
  })
  handleBlur(idx)
}}

The handleChange function updates notificationsRef.current but the parent component's value prop is not updated, so the saved templates still contain the old value.

Environment

  • Donetick version: latest self-hosted
  • Frontend: React (Ionic) app
  • Database: SQLite

Impact

Users cannot set custom reminder times. Any value other than the smart suggestion defaults (1, 30, etc.) is silently ignored, leading to reminders firing at incorrect times (e.g., 1 minute before instead of 5 minutes before).

Workaround found

The value only commits when the input field loses focus (the onBlur event). If you type a value and save without tabbing first, the old value is silently kept.

Workaround: After typing the desired value, press Tab before saving. The description will update to match the new value, and it will save correctly.

Root cause clue: The draftValues state holds the typed value, but it's only merged into the notification templates array in the onBlur handler. Saving directly doesn't trigger that commit. Users who type a value and immediately save — which is the natural workflow — lose their custom values.

Note on reproduction: The mismatch between the input field and the reminder label (e.g., input shows "5", label still shows "1 min before due") is the visible symptom. Tabbing out resolves the mismatch and allows the value to save.


Happy to provide more details or test a fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions