Add Backdate Memos feature — Set custom creation dates when writing new memos#5847
Add Backdate Memos feature — Set custom creation dates when writing new memos#5847PeriBluGaming wants to merge 6 commits into
Conversation
… past dates Agent-Logs-Url: https://github.com/PeriBluGaming/memos/sessions/541e7a43-b75b-4720-9408-246422b8d4f4 Co-authored-by: PeriBluGaming <196774698+PeriBluGaming@users.noreply.github.com>
…one issues Agent-Logs-Url: https://github.com/PeriBluGaming/memos/sessions/541e7a43-b75b-4720-9408-246422b8d4f4 Co-authored-by: PeriBluGaming <196774698+PeriBluGaming@users.noreply.github.com>
feat: add backdate popover to create memos with past dates
Agent-Logs-Url: https://github.com/PeriBluGaming/memos/sessions/4b1ea44c-6e4c-4dac-8466-b7a3cb670ead Co-authored-by: PeriBluGaming <196774698+PeriBluGaming@users.noreply.github.com>
docs: add backdating feature to README
📝 WalkthroughWalkthroughThis pull request adds a new "Backdate Memos" feature that allows users to set a custom creation date for new memos. It introduces a Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant MemoEditor as MemoEditor
participant BackdatePopover as BackdatePopover
participant ActionDispatch as Redux/Actions
User->>BackdatePopover: Clicks calendar icon
BackdatePopover->>BackdatePopover: Opens popover, sets open state
User->>BackdatePopover: Enters datetime value
BackdatePopover->>BackdatePopover: Parses datetime-local string
BackdatePopover->>BackdatePopover: Converts to Date (local time)
BackdatePopover->>ActionDispatch: Dispatches setTimestamps({createTime: date})
ActionDispatch->>MemoEditor: Updates memo createTime
User->>BackdatePopover: Clicks clear action (X icon)
BackdatePopover->>ActionDispatch: Dispatches setTimestamps({createTime: undefined})
ActionDispatch->>MemoEditor: Clears createTime
BackdatePopover->>BackdatePopover: Closes popover
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/components/MemoEditor/components/TimestampPopover.tsx (1)
143-148: Consider constraining the picker to past/current dates.The feature is scoped as "Backdate Memos" (README, PR description), but the
datetime-localinput has nomaxattribute, so users can just as easily pick a future date. If future-dating is also an intended use case, ignore this; otherwise addmax={toDatetimeLocalValue(new Date())}(refreshed on open) to match the documented intent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/MemoEditor/components/TimestampPopover.tsx` around lines 143 - 148, The datetime-local input in TimestampPopover.tsx allows future dates but this feature is scoped for backdating; add a max attribute to the input using toDatetimeLocalValue(new Date()) so users cannot pick future timestamps (i.e. <input ... max={toDatetimeLocalValue(new Date())} />), and ensure that value is refreshed when the popover opens (update the max value in the handler or a useEffect triggered by the popover open state) to keep the limit current; reference the input element, createTime value, toDatetimeLocalValue helper and handleDateChange in your change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/MemoEditor/components/TimestampPopover.tsx`:
- Around line 107-118: handleDateChange currently returns early when the
datetime-local input is emptied, leaving a stale createTime in state; update
handleDateChange to detect an empty value and dispatch actions.setTimestamps({
createTime: null }) (or undefined per existing state shape) to clear the
timestamp, otherwise continue parsing and dispatching the new Date as before so
clearing the input mirrors the explicit clear button behavior.
---
Nitpick comments:
In `@web/src/components/MemoEditor/components/TimestampPopover.tsx`:
- Around line 143-148: The datetime-local input in TimestampPopover.tsx allows
future dates but this feature is scoped for backdating; add a max attribute to
the input using toDatetimeLocalValue(new Date()) so users cannot pick future
timestamps (i.e. <input ... max={toDatetimeLocalValue(new Date())} />), and
ensure that value is refreshed when the popover opens (update the max value in
the handler or a useEffect triggered by the popover open state) to keep the
limit current; reference the input element, createTime value,
toDatetimeLocalValue helper and handleDateChange in your change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f0115d54-93c6-4cdd-97c3-8aa18c0c13db
📒 Files selected for processing (6)
README.mdweb/src/components/MemoEditor/components/TimestampPopover.tsxweb/src/components/MemoEditor/components/index.tsweb/src/components/MemoEditor/index.tsxweb/src/locales/de.jsonweb/src/locales/en.json
| const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
| const value = e.target.value; | ||
| if (!value) return; | ||
| // Parse datetime-local value (YYYY-MM-DDTHH:mm) as local time explicitly | ||
| const [datePart, timePart] = value.split("T"); | ||
| const [year, month, day] = datePart.split("-").map(Number); | ||
| const [hours, minutes] = timePart.split(":").map(Number); | ||
| const date = new Date(year, month - 1, day, hours, minutes); | ||
| if (!Number.isNaN(date.getTime())) { | ||
| dispatch(actions.setTimestamps({ createTime: date })); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Clearing the datetime input leaves a stale createTime.
When the user clears the native datetime-local field (empty string), handleDateChange early-returns, so a previously set createTime stays in state even though the UI shows an empty picker. Expected behavior would be to clear createTime when the value is emptied (mirroring the explicit clear button).
🛠️ Suggested fix
const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
- if (!value) return;
+ if (!value) {
+ dispatch(actions.setTimestamps({ createTime: undefined }));
+ return;
+ }
// Parse datetime-local value (YYYY-MM-DDTHH:mm) as local time explicitly🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@web/src/components/MemoEditor/components/TimestampPopover.tsx` around lines
107 - 118, handleDateChange currently returns early when the datetime-local
input is emptied, leaving a stale createTime in state; update handleDateChange
to detect an empty value and dispatch actions.setTimestamps({ createTime: null
}) (or undefined per existing state shape) to clear the timestamp, otherwise
continue parsing and dispatching the new Date as before so clearing the input
mirrors the explicit clear button behavior.
Feature
Adds the ability to set a custom creation date when writing a new memo, allowing users to place memos anywhere on their timeline.
Use Cases
Changes
Testing
Summary by CodeRabbit
New Features
Documentation