feat(calendar): natural language time parsing in event title - #8505
Open
miaulalala wants to merge 1 commit into
Open
feat(calendar): natural language time parsing in event title#8505miaulalala wants to merge 1 commit into
miaulalala wants to merge 1 commit into
Conversation
miaulalala
requested review from
GVodyanov,
SebastianKrupinski and
tcitworld
as code owners
June 15, 2026 17:19
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Parses times and dates typed into the event title, e.g. 'lunch tomorrow at 1pm', and offers them as a dismissible suggestion that fills the start and end fields. Uses chrono-node, with a European day-first date parser prepended so '01/02' reads as 1 February. Adds naturalLanguageTimeParserService, a TimeSuggestion component and a TimeSuggestionMixin, wired into both the full and simple editors, plus 94 unit tests. AI-Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
miaulalala
force-pushed
the
feat/natural-language-time-parsing
branch
from
September 1, 2026 18:20
a63d384 to
8102b13
Compare
hamza221
self-requested a review
September 2, 2026 10:22
GVodyanov
reviewed
Sep 2, 2026
|
|
||
| <template> | ||
| <div class="time-suggestion" role="status" aria-live="polite"> | ||
| <ClockOutlineIcon :size="16" class="time-suggestion__icon" decorative /> |
Contributor
There was a problem hiding this comment.
Suggested change
| <ClockOutlineIcon :size="16" class="time-suggestion__icon" decorative /> | |
| <ClockOutlineIcon :size="20" class="time-suggestion__icon" decorative /> |
We try to keep them 20 when possible
Comment on lines
+38
to
+53
| const chronoInstances = { | ||
| en: buildInstance(chrono.en), | ||
| de: buildInstance(chrono.de), | ||
| fr: buildInstance(chrono.fr), | ||
| es: buildInstance(chrono.es), | ||
| it: buildInstance(chrono.it), | ||
| nl: buildInstance(chrono.nl), | ||
| pt: buildInstance(chrono.pt), | ||
| ru: buildInstance(chrono.ru), | ||
| uk: buildInstance(chrono.uk), | ||
| sv: buildInstance(chrono.sv), | ||
| fi: buildInstance(chrono.fi), | ||
| ja: buildInstance(chrono.ja), | ||
| vi: buildInstance(chrono.vi), | ||
| 'zh-hans': buildInstance(chrono.zh.hans), | ||
| 'zh-hant': buildInstance(chrono.zh.hant), |
Contributor
There was a problem hiding this comment.
So we only support these languages here? Not a critique, just trying to understand
Contributor
Author
There was a problem hiding this comment.
yes - the library has a limited set of languages, so that's why they're listed instead of being a generalised feature
Contributor
Contributor
Author
hamza221
requested changes
Sep 2, 2026
Comment on lines
+138
to
+154
| if (end && end.isCertain('hour')) { | ||
| // Time range: "10:00 – 14:00", "10am to 2pm" | ||
| const sh = start.get('hour') | ||
| const sm = start.get('minute') ?? 0 | ||
| const eh = end.get('hour') | ||
| const em = end.get('minute') ?? 0 | ||
| return { | ||
| type: 'time-range', | ||
| startHour: sh, | ||
| startMinute: sm, | ||
| endHour: eh, | ||
| endMinute: em, | ||
| displayText: `${formatTimeParts(sh, sm)} – ${formatTimeParts(eh, em)}`, | ||
| matchedText: result.text, | ||
| matchedIndex: result.index, | ||
| } | ||
| } |
Contributor
| @@ -0,0 +1,240 @@ | |||
| /** | |||
Contributor
| @@ -0,0 +1,240 @@ | |||
| /** | |||
Contributor
| @@ -0,0 +1,240 @@ | |||
| /** | |||
Contributor
Comment on lines
+38
to
+54
| const chronoInstances = { | ||
| en: buildInstance(chrono.en), | ||
| de: buildInstance(chrono.de), | ||
| fr: buildInstance(chrono.fr), | ||
| es: buildInstance(chrono.es), | ||
| it: buildInstance(chrono.it), | ||
| nl: buildInstance(chrono.nl), | ||
| pt: buildInstance(chrono.pt), | ||
| ru: buildInstance(chrono.ru), | ||
| uk: buildInstance(chrono.uk), | ||
| sv: buildInstance(chrono.sv), | ||
| fi: buildInstance(chrono.fi), | ||
| ja: buildInstance(chrono.ja), | ||
| vi: buildInstance(chrono.vi), | ||
| 'zh-hans': buildInstance(chrono.zh.hans), | ||
| 'zh-hant': buildInstance(chrono.zh.hant), | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.









Summary
Adds natural language time/date parsing to the event title field in both the popover (EditSimple) and full (EditFull) editors. When the user types a recognised time or date expression, a dismissible suggestion banner appears below the title input.
Supported patterns:
2pm,14:00,9am10:00 - 14:00,10am to 2pmJuly 23,23.07.26,07/23/2026June 1 to June 3,June 1-3July 23 4pm,14.08.2026 19:00all day,all-daytomorrow,next Monday,this Friday,in 3 days,next weeknext Friday 14:00Multi-language support via chrono-node locale routing based on
getLanguage():de,fr,es,it,nl,pt,ru,uk,sv,fi,ja,vi,zh-hans,zh-hant, with English fallback for unsupported locales.Implementation:
src/services/naturalLanguageTimeParserService.js— parsing logic using chrono-node with a custom European DD.MM.YY parser prepended for prioritysrc/components/Editor/Properties/TimeSuggestion.vue— suggestion banner componentsrc/mixins/TimeSuggestionMixin.js— shared mixin consumed by both editor viewsScreenshot
AI disclosure
This PR was developed with assistance from Claude Code (claude-sonnet-4-6).
Test plan
2pmin the title → suggestion banner appears showing "Set time: 14:00"all day→ banner shows "Mark as all-day event", apply toggles all-dayJune 1 to June 3→ banner shows date range, apply sets both dates as all-daytomorrow 3pm→ banner shows datetime, apply sets date and timenext Monday→ banner shows date, apply sets all-day on that Monday15. Juli→ suggestion appearsnpm run test:unit