Skip to content

feat(core): add duration date pipes (#DS-4652) - #1843

Merged
lskramarov merged 3 commits into
mainfrom
feat/DS-4652
Aug 5, 2026
Merged

feat(core): add duration date pipes (#DS-4652)#1843
lskramarov merged 3 commits into
mainfrom
feat/DS-4652

Conversation

@lskramarov

Copy link
Copy Markdown
Contributor

No description provided.

@lskramarov lskramarov self-assigned this Aug 5, 2026
@lskramarov lskramarov added the enhancement New feature or request label Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 6f6bc7d):

https://koobiq-next--prs-1843-rhllcdmy.web.app

(expires Sat, 08 Aug 2026 12:51:03 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the core formatter/pipes surface by adding duration-formatting pipes (both legacy and kbq* locale-aware variants), improves pipe robustness for missing/invalid range inputs, and updates docs/dev examples plus unit tests to cover the new behavior.

Changes:

  • Added duration pipes (duration* and kbqDuration*) and wired them into KbqFormattersModule exports/public API.
  • Hardened range/duration pipe input handling (missing/invalid bounds) and improved BaseLocaleAwareFormatterPipe caching to tolerate shallow-rebuilt array inputs.
  • Updated formatter documentation (RU/EN), dev showcase page, and Jest specs to cover duration pipes and missing-bound behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/public_api_guard/components/core.api.md Public API snapshot updates to include duration pipes and signature/name adjustments.
packages/components/core/formatters/index.ts Registers and exports new duration pipes via KbqFormattersModule.
packages/components/core/formatters/date/formatter.pipe.ts Implements duration pipes, safer range parsing helpers, and shallow array equality for caching.
packages/components/core/formatters/date/formatter.spec.ts Adds tests for duration pipes, locale reactivity, caching, and missing-bound range behavior.
packages/components/core/formatters/date/date-formatter.ru.md Documents pipe families (kbq* vs legacy), durations, opened ranges, and invalid input behavior (RU).
packages/components/core/formatters/date/date-formatter.en.md Same documentation expansion for EN.
packages/components-dev/date-pipes/template.html Adds UI/docs and examples for duration pipes + locale toggle behavior.
packages/components-dev/date-pipes/module.ts Adds locale toggle and duration demo data population; injects locale service via token.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/components/core/formatters/date/formatter.pipe.ts
Comment thread packages/components/core/formatters/date/formatter.spec.ts Outdated
Comment thread packages/components/core/formatters/index.ts
@lskramarov

Copy link
Copy Markdown
Contributor Author

/approve-snapshots

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🔄 Updating snapshots.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ No snapshot changes detected.

Adds `durationShortest`, `durationLong` and `durationShort` in all three existing
flavours -- pure, `...ImpurePipe` and locale-aware `kbq*` -- so the duration formats
are usable from a template instead of only through `DateFormatter`. They take a
`[from, to]` tuple, like the range pipes.

Two behaviour changes to the existing pipes come with it:

- The range pipes no longer throw when neither bound is a date. `[null, null]`
  reached `openedRangeDate(null, null)`, which throws and aborts the rendering of
  the whole view -- reachable as soon as a range form control is left empty. They
  now render an empty string, and so do the duration pipes for a missing,
  unparseable or reversed range. `DateAdapter.deserialize()` returns a truthy
  *invalid* date for an unparseable value, so the previous `date ? ... : ''` guards
  never caught malformed input; an invalid bound is now treated as an absent one.

- `BaseLocaleAwareFormatterPipe` compares array inputs element-wise. A `[from, to]`
  tuple rebuilt on every change detection cycle -- from a getter or a `computed()` --
  missed the cache every tick, which is the most expensive case for durations.

Also documents the three pipe families in date-formatter.{en,ru}.md, where the 13
`kbq*` pipes were undocumented, and adds a duration section and a locale toggle to
the date-pipes dev app.
Copilot review: the range and duration helpers were widened to `null | undefined`
in the previous commit, but the pipes' own signatures still demanded
`D[] | string[]`, so strict template type-checking rejected a range that has not
been populated yet even though the runtime handled it. Widens every date pipe
input to include `null | undefined`, single-value ones as well -- a `date | null`
field is at least as common as an empty range, and the docs already promised an
empty string for it.

Testing that promise turned up the same defect the range guards fixed, still live
in the single-value pipes: `deserialize()` answers an unparseable string with a
truthy *invalid* date, which passes the `date ? ... : ''` check and then makes the
formatter throw "Cannot format invalid date", aborting the rendering of the whole
view. They now go through `toValidDate` like the range pipes do.

Also drops the `as RangeValue` casts in the spec by widening `RangeValue` itself,
which is what the second review comment asked for -- the casts were hiding exactly
the mismatch above.
@lskramarov
lskramarov merged commit 7c3ec4e into main Aug 5, 2026
11 checks passed
@lskramarov
lskramarov deleted the feat/DS-4652 branch August 5, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants