You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(AuditLog): Add the organisation audit log page - #8940
The organisation audit log page, on the endpoints from #8921. It sits behind the organisation_audit_log flag and is shown to organisation admins only.
New Audit Log tab in the organisation nav.
Logs grouped by day. Each row shows the project and environment, and expands to the field changes. When a log has no field changes, the row links to the related object instead.
Search, Clear all and paging. The search lives in the URL.
Loading, empty, no access and error states.
A new list rather than the project page's AuditLog: it uses no Flux stores, so the project page can move onto it later.
Shared changes, not behind the flag:
Accordion gets a controlled open and a row variant, and the rows use it. Its other users (release pipeline status, environment metrics, pending change requests) keep the card look.
ColorSwatch takes children and an xl size. The project initial in each row is built on it.
The project palette and contrast colour move out of Utils into paletteColour, so Jest can test them. Utils still exports them, so existing callers don't change.
New --always-black token, the pair of --always-white, for the initial on light palette colours.
Next: filtering by scope (#8941), then the stories and the RTL tests.
How did you test this code?
Unit tests for the filters, URL round trip, day grouping, error kinds, related object links and palette colours.
By hand against a local API: with the flag on, open Organisation → Audit Log, search, expand a row and page through.
It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.
No actionable comments were generated in the recent review.
Walkthrough
Adds organisation audit-log queries and types, plus a feature-gated organisation page with filtering, paging and expanded change details. Adds audit-log display components and helpers for grouping, labelling, error handling and related-object links. Updates Accordion and ColorSwatch, adds project-colour utilities and theme tokens, and moves version-limit checking into a shared utility.
The organisation audit log page is flag-gated and has a few small UI correctness gaps: a pending search can reappear after navigating away, emoji project initials render broken, a filter can restore an old page, and a failed permission check shows no error. None of these is likely to block use, so the change is mergeable with follow-up fixes.
- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 4fbefb16-abe3-497c-aa4c-4ddd5012016a
Commits
Reviewing files that changed from the base of the PR and between cdb50e5 and d6908d2.
Files ignored due to path filters: 1
frontend/documentation/TokenReference.generated.stories.tsx is excluded by !**/*.generated.*
Files selected for processing: 1
frontend/common/utils/paletteColour.ts
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
1 issue found across 56 files
Confidence score: 5/5
auditLogFilters.test.ts is missing the required Given/When/Then markers, which makes the tests less consistent with the expected structure. Add the markers to each test.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/web/components/audit-log/__tests__/auditLogFilters.test.ts">
<violation number="1" location="frontend/web/components/audit-log/__tests__/auditLogFilters.test.ts:8">
P3: These tests omit the required Given/When/Then structure. Add `// Given`, `// When`, and `// Then` markers to each test.</violation>
</file>
Reply to a comment to ask cubic a question or push back. It learns from your replies. Click Fix with cubic on a comment, or reply @cubic-dev-ai fix this, and cubic writes the fix.
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
0 issues found across 1 file (changes from recent commits).
Confidence score: 5/5
Automated review surfaced no issues in the provided summaries.
No files require special attention.
Requires human review: Auto-approval blocked by 10 unresolved issues from previous reviews. Tip: Get a Slack DM when cubic finishes reviewing your PRs. Connect Slack
…eir own module
Utils pulls in Flux stores, so its functions can't be tested with Jest. Utils still re-exports them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Behind organisation_audit_log, for organisation admins: logs grouped by day, rows that expand to their changes, search kept in the URL, and paging.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.
The Projects page orders tiles by name with capitals first, while the
projects query sorts ignoring case, so some initials got another colour.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The reason will be displayed to describe this comment to others. Learn more.
4 issues found across 58 files
Confidence score: 3/5
isVersionOverLimit.ts treats a zero-day limit as unlimited, leaving old version rows linkable. Treat only null and undefined as unlimited.
OrganisationAuditLogPage.tsx hides the upgrade banner for the configured zero-day free-plan limit. Check for null or undefined instead of using a truthiness check.
AuditLogList.tsx can briefly show “No changes match” while a filter refetch is still loading. Gate the empty state on !isLoading.
auditLogError.ts doesn’t recognize the audit endpoint’s timeout response, so timed-out searches show a generic error. Classify the endpoint’s actual timeout response.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/common/utils/isVersionOverLimit.ts">
<violation number="1" location="frontend/common/utils/isVersionOverLimit.ts:8">
P2: A zero-day limit means feature history is unavailable, but this guard treats it like no limit and leaves old version rows linkable. Treat only `null`/`undefined` as unlimited and compare zero-day limits normally.</violation>
</file>
<file name="frontend/web/components/pages/OrganisationAuditLogPage.tsx">
<violation number="1" location="frontend/web/components/pages/OrganisationAuditLogPage.tsx:81">
P2: `0` is the configured free-plan limit and the API applies it, but this truthiness check suppresses the upgrade banner. Check for `null`/`undefined` so zero-day plans see why their log is empty.</violation>
</file>
<file name="frontend/web/components/audit-log/AuditLogList/AuditLogList.tsx">
<violation number="1" location="frontend/web/components/audit-log/AuditLogList/AuditLogList.tsx:39">
P2: A refetch with a previously empty result returns the empty state while the request is still loading, so changing filters can briefly show “No changes match” before new results arrive. Gate the empty state on `!isLoading` and render loading rows when an empty result is being fetched.</violation>
</file>
<file name="frontend/web/components/audit-log/auditLogError.ts">
<violation number="1" location="frontend/web/components/audit-log/auditLogError.ts:19">
P2: The audit endpoint does not translate query timeouts into a `503` response with `data.code = 'statement_timeout'`, so timed-out searches fall through to the generic error message. Classify the endpoint’s actual timeout response or add that mapping on the API side.</violation>
</file>
Reply with feedback, questions, or to request a fix.
The reason will be displayed to describe this comment to others. Learn more.
P2: A zero-day limit means feature history is unavailable, but this guard treats it like no limit and leaves old version rows linkable. Treat only null/undefined as unlimited and compare zero-day limits normally.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At frontend/common/utils/isVersionOverLimit.ts, line 8:
<comment>A zero-day limit means feature history is unavailable, but this guard treats it like no limit and leaves old version rows linkable. Treat only `null`/`undefined` as unlimited and compare zero-day limits normally.</comment>
<file context>
@@ -0,0 +1,13 @@
+ versionLimitDays: number | null | undefined,
+ date: string | undefined,
+) {
+ if (!versionLimitDays) {
+ return false
+ }
</file context>
The reason will be displayed to describe this comment to others. Learn more.
P2: 0 is the configured free-plan limit and the API applies it, but this truthiness check suppresses the upgrade banner. Check for null/undefined so zero-day plans see why their log is empty.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At frontend/web/components/pages/OrganisationAuditLogPage.tsx, line 81:
<comment>`0` is the configured free-plan limit and the API applies it, but this truthiness check suppresses the upgrade banner. Check for `null`/`undefined` so zero-day plans see why their log is empty.</comment>
<file context>
@@ -0,0 +1,133 @@
+ {isAdminChecked && !isAdmin && <AuditLogNoAccess />}
+ {isAdmin && (
+ <div className='d-flex flex-column gap-3'>
+ {!!auditLimitDays && (
+ <PlanBasedBanner
+ force
</file context>
The reason will be displayed to describe this comment to others. Learn more.
P2: A refetch with a previously empty result returns the empty state while the request is still loading, so changing filters can briefly show “No changes match” before new results arrive. Gate the empty state on !isLoading and render loading rows when an empty result is being fetched.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At frontend/web/components/audit-log/AuditLogList/AuditLogList.tsx, line 39:
<comment>A refetch with a previously empty result returns the empty state while the request is still loading, so changing filters can briefly show “No changes match” before new results arrive. Gate the empty state on `!isLoading` and render loading rows when an empty result is being fetched.</comment>
<file context>
@@ -0,0 +1,80 @@
+
+ const isFirstLoad = isLoading && !items
+
+ if (!isFirstLoad && !items?.length) {
+ return (
+ <AuditLogListEmpty
</file context>
The reason will be displayed to describe this comment to others. Learn more.
P2: The audit endpoint does not translate query timeouts into a 503 response with data.code = 'statement_timeout', so timed-out searches fall through to the generic error message. Classify the endpoint’s actual timeout response or add that mapping on the API side.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At frontend/web/components/audit-log/auditLogError.ts, line 19:
<comment>The audit endpoint does not translate query timeouts into a `503` response with `data.code = 'statement_timeout'`, so timed-out searches fall through to the generic error message. Classify the endpoint’s actual timeout response or add that mapping on the API side.</comment>
<file context>
@@ -0,0 +1,21 @@
+ 'code' in error.data
+ ? error.data.code
+ : undefined
+ if (error.status === 503 && code === 'statement_timeout') return 'timeout'
+ return 'unknown'
+}
</file context>
This branch was successfully deployed
2 active
deployments
Preview – flagsmith-frontend-staging—d6908d27DeployedNov 13, 2026 by
vercel[bot]
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
featureNew feature or requestfront-endIssue related to the React Front End Dashboard
3 participants
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.
Thanks for submitting a PR! Please check the boxes below:
docs/if required so people know about the feature.Changes
Contributes to #8889
The organisation audit log page, on the endpoints from #8921. It sits behind the
organisation_audit_logflag and is shown to organisation admins only.A new list rather than the project page's
AuditLog: it uses no Flux stores, so the project page can move onto it later.Shared changes, not behind the flag:
Accordiongets a controlledopenand arowvariant, and the rows use it. Its other users (release pipeline status, environment metrics, pending change requests) keep the card look.ColorSwatchtakes children and anxlsize. The project initial in each row is built on it.UtilsintopaletteColour, so Jest can test them.Utilsstill exports them, so existing callers don't change.--always-blacktoken, the pair of--always-white, for the initial on light palette colours.Next: filtering by scope (#8941), then the stories and the RTL tests.
How did you test this code?