Skip to content

Add changelog feature to ACP menu#978

Merged
Gkrumbach07 merged 1 commit intoambient-code:mainfrom
syntaxsdev:feat/changelog
Mar 24, 2026
Merged

Add changelog feature to ACP menu#978
Gkrumbach07 merged 1 commit intoambient-code:mainfrom
syntaxsdev:feat/changelog

Conversation

@syntaxsdev
Copy link
Copy Markdown
Contributor

@syntaxsdev syntaxsdev commented Mar 20, 2026

As per ticket, changelog button with modal and a gift box icon.

Demo:

image image

Changelog comes from Github release changelog - and in future can be reconsidered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 20, 2026

Walkthrough

A new "Recent Updates Dialog" feature is introduced that displays GitHub releases in a dialog component, fetches release data via a new API client and React Query hook, tracks unseen updates in local storage, and integrates into the application's navigation UI alongside existing controls.

Changes

Cohort / File(s) Summary
Recent Updates Dialog Component
components/frontend/src/components/recent-updates-dialog.tsx, components/frontend/src/components/__tests__/recent-updates-dialog.test.tsx
New dialog component that fetches and displays GitHub releases with loading/error/empty states, unseen updates notification badge, markdown-formatted release body, and local storage persistence of last-seen timestamp. Comprehensive test suite verifies trigger rendering, state conditions, dialog interactions, and content display.
Navigation Integration
components/frontend/src/app/projects/[name]/layout.tsx, components/frontend/src/components/navigation.tsx
Integrated RecentUpdatesDialog component into desktop and mobile navigation sections alongside existing controls like ThemeToggle and integrations button.
GitHub Releases API & Query Layer
components/frontend/src/services/api/github-releases.ts, components/frontend/src/services/queries/use-github-releases.ts
New API client module with getGitHubReleases() function and GitHubRelease type definition. React Query hook useGitHubReleases() wraps the API with 15-minute stale time, retry limit of 1, and disabled window-focus refetch.

Sequence Diagram

sequenceDiagram
    actor User
    participant Dialog as RecentUpdatesDialog
    participant Query as useGitHubReleases
    participant API as GitHub API
    participant Storage as localStorage

    User->>Dialog: Click trigger button
    Dialog->>Storage: Read 'acp-last-seen-updates'
    Dialog->>Query: Fetch releases (if not cached)
    Query->>API: GET /repos/.../releases
    API-->>Query: Release data
    Query-->>Dialog: Return releases
    Dialog->>Dialog: Compare latest release.published_at<br/>vs lastSeen timestamp
    Dialog->>Storage: Write current ISO time<br/>to 'acp-last-seen-updates'
    Dialog->>Dialog: Show notification badge<br/>if unseen releases exist
    Dialog->>User: Render dialog with<br/>release list & details
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a changelog feature (displaying GitHub releases) to the ACP menu with a dialog component.
Description check ✅ Passed The PR description clearly relates to the changeset: it describes adding a changelog feature with a gift box icon button and modal dialog that displays GitHub releases.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/frontend/src/components/__tests__/recent-updates-dialog.test.tsx`:
- Around line 61-78: Replace brittle DOM class selection in the
RecentUpdatesDialog tests with a stable test id: add a data-testid="unseen-dot"
to the notification span in the RecentUpdatesDialog component (the element that
currently has the red dot) and update the two tests in
recent-updates-dialog.test.tsx to use screen.queryByTestId('unseen-dot') (or
getByTestId when expecting presence) instead of
button.querySelector('.bg-red-500'); keep the same assertions (presence/absence)
and leave mockUseLocalStorage/mockSetLastSeen behavior unchanged.

In `@components/frontend/src/components/recent-updates-dialog.tsx`:
- Around line 27-30: The current hasUnseen check assumes releases[0] is the
newest; instead compute the latest release by published_at before comparing to
lastSeen: find the release with the max published_at (e.g., via
Array.prototype.reduce or sorting) from the releases array, then compare new
Date(latest.published_at) to new Date(lastSeen) to set hasUnseen (referencing
the hasUnseen variable, releases array, and lastSeen variable); update the logic
so it handles empty arrays and null/undefined published_at safely.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 451d7ee8-ab64-44db-95d4-43462f47d78f

📥 Commits

Reviewing files that changed from the base of the PR and between cdf2f6f and e086455.

📒 Files selected for processing (6)
  • components/frontend/src/app/projects/[name]/layout.tsx
  • components/frontend/src/components/__tests__/recent-updates-dialog.test.tsx
  • components/frontend/src/components/navigation.tsx
  • components/frontend/src/components/recent-updates-dialog.tsx
  • components/frontend/src/services/api/github-releases.ts
  • components/frontend/src/services/queries/use-github-releases.ts

Comment on lines +61 to +78
it('shows red dot when unseen releases exist', () => {
render(<RecentUpdatesDialog />);
const button = screen.getByRole('button', { name: /recent updates/i });
const dot = button.querySelector('.bg-red-500');
expect(dot).not.toBeNull();
});

it('hides red dot when all releases are seen', () => {
mockUseLocalStorage.mockReturnValue([
'2026-03-19T00:00:00Z',
mockSetLastSeen,
vi.fn(),
]);
render(<RecentUpdatesDialog />);
const button = screen.getByRole('button', { name: /recent updates/i });
const dot = button.querySelector('.bg-red-500');
expect(dot).toBeNull();
});
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.

🧹 Nitpick | 🔵 Trivial

Tests look good; consider using a data-testid for the notification dot.

Using .querySelector('.bg-red-500') is brittle—if the Tailwind class changes, these tests will break silently. Consider adding a data-testid="unseen-dot" attribute to the notification span for more resilient testing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/frontend/src/components/__tests__/recent-updates-dialog.test.tsx`
around lines 61 - 78, Replace brittle DOM class selection in the
RecentUpdatesDialog tests with a stable test id: add a data-testid="unseen-dot"
to the notification span in the RecentUpdatesDialog component (the element that
currently has the red dot) and update the two tests in
recent-updates-dialog.test.tsx to use screen.queryByTestId('unseen-dot') (or
getByTestId when expecting presence) instead of
button.querySelector('.bg-red-500'); keep the same assertions (presence/absence)
and leave mockUseLocalStorage/mockSetLastSeen behavior unchanged.

Comment on lines +27 to +30
const hasUnseen =
releases &&
releases.length > 0 &&
(!lastSeen || new Date(releases[0].published_at) > new Date(lastSeen));
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.

🧹 Nitpick | 🔵 Trivial

Minor: Assumption about release ordering.

The hasUnseen logic assumes releases[0] is the most recent release. GitHub's API sorts releases by created_at (not published_at) by default. These timestamps are usually identical, but could differ if a release is created as a draft and published later.

This is low-risk since it only affects edge cases, but worth noting if the notification dot behavior seems incorrect for some releases.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/frontend/src/components/recent-updates-dialog.tsx` around lines 27
- 30, The current hasUnseen check assumes releases[0] is the newest; instead
compute the latest release by published_at before comparing to lastSeen: find
the release with the max published_at (e.g., via Array.prototype.reduce or
sorting) from the releases array, then compare new Date(latest.published_at) to
new Date(lastSeen) to set hasUnseen (referencing the hasUnseen variable,
releases array, and lastSeen variable); update the logic so it handles empty
arrays and null/undefined published_at safely.

@ambient-code ambient-code bot added this to the Review Queue milestone Mar 23, 2026
@Gkrumbach07 Gkrumbach07 merged commit 8475f53 into ambient-code:main Mar 24, 2026
28 checks passed
@ambient-code ambient-code bot removed this from the Review Queue milestone Mar 24, 2026
jeremyeder pushed a commit to jeremyeder/platform that referenced this pull request Mar 26, 2026
As per ticket, changelog button with modal and a gift box icon.

Demo:

<img width="429" height="70" alt="image"
src="https://github.com/user-attachments/assets/50a575c8-46b8-44f3-a647-b08a8458f253"
/>

<img width="827" height="1352" alt="image"
src="https://github.com/user-attachments/assets/8a167d24-7144-4696-acf1-cd44f51794e5"
/>

Changelog comes from Github release changelog - and in future can be
reconsidered.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants