Skip to content

Conversation

@RishiChaubey31
Copy link
Contributor

@RishiChaubey31 RishiChaubey31 commented Oct 29, 2025

Date: 30-10-2025

Developer Name: Rishi Chaubey


Issue Ticket Number

Description

Currently, our dashboard site has an Activity Feed powered by the Logs API that tracks and displays user activities.
On the status site, we already have a calendar component with a user search option (by username), but it is non-functional.

The goal of this task is to integrate the relevant APIs with the calendar so that when a username is entered, the calendar dynamically displays the user’s activities in a structured and visually intuitive way.

  • this pr contains the code to show the OOO dates of users on calendar

Documentation Updated?

  • Yes
  • No

Under Feature Flag

  • Yes
  • No

Database Changes

  • Yes
  • No

Breaking Changes

  • Yes
  • No

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1
Screen.Recording.2025-10-30.195817.mp4

Test Coverage

Test will be in next pr updating the coverage soon !

Screenshot 1

Additional Notes

Description by Korbit AI

What change is being made?

Implement feature to show active tasks on calendar by integrating logs fetching, building per-date activity mappings, and linking GitHub issues when available. Add a development flow that fetches task logs, derives active date ranges from task details, and displays links in calendar messages. Also enhance the calendar page to optionally use this dev flow when the dev query parameter is true.

Why are these changes being made?

To display active task periods directly on the calendar and provide quick access to related GitHub issues during development, while preserving existing behavior for non-dev usage. This enables a richer, interactive calendar experience with minimal disruption to the default flow.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

@vercel
Copy link

vercel bot commented Oct 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
status-app Error Error Nov 1, 2025 4:49pm
website-status Error Error Nov 1, 2025 4:49pm

@coderabbitai
Copy link

coderabbitai bot commented Oct 29, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Out of Office (OOO) support to calendar, displaying request details and date ranges directly on the calendar view.
    • Introduced developer mode to view activity logs integrated with the calendar.
  • UI/UX Improvements

    • Enhanced calendar message display with improved formatting, line breaks, and styled links for better readability.

Walkthrough

This PR introduces Out-of-Office (OOO) logs integration to the calendar system by adding a new logs API slice, updating components to fetch and display OOO data, and enhancing the calendar UI to show OOO status alongside existing user status information. Test files are updated to use Jest fake timers for consistent time-relative assertions.

Changes

Cohort / File(s) Summary
Test Updates
__tests__/Unit/Components/ExtensionRequest/ExtensionStatusModal.test.tsx, __tests__/Unit/Components/Tasks/Card.test.tsx
Updated tests to use Jest fake timers (ExtensionStatusModal) and moment mocking (Card) for consistent relative time formatting assertions.
Logs API Integration
src/app/services/logsApi.ts, src/app/services/api.ts
Introduced new logs API slice with RTK Query endpoint getLogsByUsername accepting username, dev, format, and type parameters; exported hook useGetLogsByUsernameQuery. Added 'Logs' tag type to main API slice for cache invalidation.
Component Updates
src/components/Calendar/UserSearchField.tsx
Extended SearchField to wire logs data retrieval via useGetLogsByUsernameQuery (dev-mode only), added optional dev prop, updated onSearchTextSubmitted callback signature to pass optional oooLogsData parameter, and added state tracking for selected user.
Calendar Page Updates
src/pages/calendar/index.tsx
Added router-based dev mode detection, enhanced tile styling and click handling to display OOO details, extended processData utility to handle OOO logs, integrated logs data flow from SearchField, and improved date/status formatting.
Utilities & Constants
src/utils/userStatusCalendar.ts, src/utils/time.ts, src/constants/url.ts
Added formatTimestampToDate utility function; introduced OOOEntry type and processOOOLogsData helper in userStatusCalendar; extended processData to return OOO entries dictionary; added OOO_REQUEST_DETAILS_URL constant.
Styling
src/styles/calendar.scss
Added white-space: pre-line and link styling (color #2563eb with #1d4ed8 hover) to .messageDiv for improved multi-line message and link display.

Sequence Diagram

sequenceDiagram
    participant User
    participant Calendar as Calendar Page
    participant SearchField as UserSearchField
    participant LogsAPI as Logs API
    participant Utils as userStatusCalendar Utils

    User->>Calendar: Selects user (with dev=true query param)
    Calendar->>SearchField: Passes dev=true prop
    SearchField->>LogsAPI: useGetLogsByUsernameQuery(username, dev, format, type)
    LogsAPI-->>SearchField: LogsResponse with entries
    SearchField->>SearchField: Triggers onSearchTextSubmitted
    SearchField->>Calendar: Passes user, data, oooLogsData
    Calendar->>Utils: processData(userId, data, oooLogsData)
    Utils->>Utils: processOOOLogsData() builds OOO entries map
    Utils-->>Calendar: [statusDict, taskDict, oooEntriesDict]
    Calendar->>Calendar: Updates tile styling with OOO status
    Calendar-->>User: Displays OOO details on day click
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • src/utils/userStatusCalendar.ts: Core logic for OOO data processing; requires careful review of date mapping, merging with existing status data, and return type changes affecting callers.
  • src/pages/calendar/index.tsx: Substantial state and data-flow changes; integration of dev mode, OOO display logic, and updated callback signatures warrant thorough verification.
  • src/components/Calendar/UserSearchField.tsx: New query hook integration and effect dependencies; verify logs data fetching logic and proper memoization/dependency tracking.
  • Test file changes use mocking patterns that should be verified to ensure proper cleanup and isolation.

Possibly related PRs

Suggested reviewers

  • iamitprakash
  • AnujChhikara
  • Achintya-Chatterjee
  • yesyash
  • MayankBansal12

Poem

🐰 Hopping through logs we go,
OOO dates now steal the show,
With calendars bright and API sleek,
Out-of-office moments peak!
Dev mode whispers what's in store,
Status messages we adore! 🗓️

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feature : Show OOO users data on Calendar" directly and accurately describes the primary objective of the changeset. The PR implements support for displaying Out-Of-Office (OOO) entries on the calendar by integrating a new Logs API, adding OOO-specific utilities, and wiring the data through the calendar component. The title is clear, specific, and concise without being misleading or off-topic.
Description Check ✅ Passed The pull request description clearly articulates the purpose and context of the changes. The author explains that the PR integrates the Logs API with the existing calendar component to display Out-Of-Office (OOO) dates for users when a username is searched. This description directly aligns with the changeset, which includes a new logs API slice (logsApi.ts), wiring of logs data in UserSearchField.tsx, calendar page enhancements to display OOO entries, and supporting utilities for processing OOO logs data. The description provides meaningful information about what is being implemented and why, avoiding generic or vague language.

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

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

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

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Status
Design Missing Type Enum for Log Types ▹ view
Readability Undefined Format Type Constant ▹ view
Design Unsafe URL Parameter Construction ▹ view
Readability Undefined Log Type Constant ▹ view
Readability Move constant array outside function ▹ view ✅ Fix detected
Security Dev mode enabled by default ▹ view ✅ Fix detected
Performance Inefficient array recreation in formatTimestampToDate ▹ view ✅ Fix detected
Security Unvalidated query string parameters ▹ view
Performance Missing dependency in useEffect causes stale closure ▹ view ✅ Fix detected
Performance Unnecessary API calls on component re-renders ▹ view ✅ Fix detected
Files scanned
File Path Reviewed
src/app/services/api.ts
src/utils/time.ts
src/app/services/logsApi.ts
src/constants/url.ts
src/utils/userStatusCalendar.ts
src/components/Calendar/UserSearchField.tsx
src/pages/calendar/index.tsx

Explore our documentation to understand the languages and file types we support and the files we ignore.

Check out our docs on how you can make Korbit work best for you and your team.

Loving Korbit!? Share us on LinkedIn Reddit and X

Copy link

@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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
__tests__/Unit/Components/Tasks/Card.test.tsx (1)

541-557: Avoid mutating moment.prototype; use a spy and restore safely

Directly overriding the prototype can leak if the test fails. Spy instead and restore in finally.

-        const originalFromNow = moment.prototype.fromNow;
-        moment.prototype.fromNow = jest.fn(() => '4 years ago');
+        const spy = jest.spyOn(moment.fn as any, 'fromNow').mockReturnValue('4 years ago');
         const { getByTestId } = renderWithRouter(
           ...
         );
         const spanElement = screen.getByTestId('started-on');
-        expect(spanElement).toHaveTextContent('Started 4 years ago');
-        moment.prototype.fromNow = originalFromNow;
+        expect(spanElement).toHaveTextContent('Started 4 years ago');
+        spy.mockRestore();

If you prefer time control over mocking, we can switch this suite to jest.setSystemTime(...) like in the other test for consistency.

♻️ Duplicate comments (5)
src/utils/time.ts (1)

29-42: Move months array to module level.

The months array is recreated on every function call, adding unnecessary overhead. This concern has already been raised in previous reviews.

src/app/services/logsApi.ts (2)

30-36: Use URLSearchParams for safe URL construction.

Template literal concatenation doesn't encode special characters. If username contains characters like &, =, or spaces, the URL will be malformed or could be exploited.

Apply this fix:

-            query: ({
-                username,
-                dev = false,
-                format = 'feed',
-                type = 'REQUEST_CREATED',
-            }) =>
-                `/logs?dev=${dev}&format=${format}&type=${type}&username=${username}`,
+            query: ({
+                username,
+                dev = false,
+                format = 'feed',
+                type = 'REQUEST_CREATED',
+            }) => {
+                const params = new URLSearchParams({
+                    dev: String(dev),
+                    format,
+                    type,
+                    username,
+                });
+                return `/logs?${params.toString()}`;
+            },

33-34: Define constants or enums for format and type values.

Magic strings like 'feed' and 'REQUEST_CREATED' reduce maintainability and type safety. This has been previously flagged.

src/components/Calendar/UserSearchField.tsx (2)

78-88: Add missing dependencies to useEffect.

The effect uses data and onSearchTextSubmitted but they're not in the dependency array, risking stale closures. This was flagged previously.

Apply this fix:

-    }, [dev, logsData, selectedUser]);
+    }, [dev, logsData, selectedUser, data, onSearchTextSubmitted]);

55-58: Memoize query parameters to prevent unnecessary re-execution.

The query parameters object is recreated on every render. While RTK Query has caching, this can still cause unnecessary work. This has been previously noted.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45c0ed5 and 2163ed1.

📒 Files selected for processing (10)
  • __tests__/Unit/Components/ExtensionRequest/ExtensionStatusModal.test.tsx (1 hunks)
  • __tests__/Unit/Components/Tasks/Card.test.tsx (3 hunks)
  • src/app/services/api.ts (1 hunks)
  • src/app/services/logsApi.ts (1 hunks)
  • src/components/Calendar/UserSearchField.tsx (4 hunks)
  • src/constants/url.ts (1 hunks)
  • src/pages/calendar/index.tsx (4 hunks)
  • src/styles/calendar.scss (1 hunks)
  • src/utils/time.ts (1 hunks)
  • src/utils/userStatusCalendar.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/app/services/logsApi.ts (1)
src/app/services/api.ts (1)
  • api (9-38)
src/utils/userStatusCalendar.ts (1)
src/app/services/logsApi.ts (1)
  • LogEntry (3-11)
__tests__/Unit/Components/ExtensionRequest/ExtensionStatusModal.test.tsx (1)
src/components/ExtensionRequest/ExtensionStatusModal.tsx (1)
  • formatToRelativeTime (24-27)
src/components/Calendar/UserSearchField.tsx (3)
src/interfaces/user.type.ts (1)
  • userDataType (1-29)
src/app/services/logsApi.ts (1)
  • LogEntry (3-11)
src/hooks/useOutsideAlerter.ts (1)
  • useOutsideAlerter (3-19)
src/pages/calendar/index.tsx (6)
__tests__/Unit/Components/Tasks/TaskDetails.test.tsx (1)
  • useRouter (706-713)
src/interfaces/user.type.ts (1)
  • userDataType (1-29)
src/utils/userStatusCalendar.ts (2)
  • OOOEntry (15-23)
  • processData (76-121)
src/utils/time.ts (1)
  • formatTimestampToDate (27-47)
src/constants/url.ts (1)
  • OOO_REQUEST_DETAILS_URL (37-37)
src/constants/calendar.ts (1)
  • MONTHS (54-67)
🪛 ast-grep (0.39.6)
src/pages/calendar/index.tsx

[warning] 91-91: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
src/pages/calendar/index.tsx

[error] 92-92: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (18.x)
🔇 Additional comments (5)
src/app/services/api.ts (1)

31-32: Tag type addition looks good; tag usage verified in logs API slice

LGTM. Verified that the logs slice correctly uses providesTags: ['Logs'] to benefit from caching with the new tag type.

src/utils/userStatusCalendar.ts (1)

53-75: Confirm timestamp units in logsApi response (seconds vs milliseconds)

The review comment raises two points:

  1. Unused second return value is confirmed: dictWithTask is created but never populated, and at line 111 only [oooEntries] is destructured from the tuple, leaving the second element wasted. Removing it simplifies the API.

  2. ? Timestamp unit normalization requires verification: The LogEntry.from and LogEntry.until fields are typed as number but their units (seconds vs milliseconds) are not documented in the codebase. The API integration code doesn't reveal the actual units returned by the backend. The suggested defensive check (logEntry.from < 1e12 ? logEntry.from * 1000 : logEntry.from) assumes a potential mismatch, but this needs confirmation.

The refactoring to remove the unused return value should proceed. However, before applying the timestamp normalization logic, please verify with the backend API documentation or team whether from/until are indeed in seconds or milliseconds.

src/constants/url.ts (1)

37-37: LGTM! Clean constant addition.

The OOO_REQUEST_DETAILS_URL constant follows the established pattern and integrates well with the existing URL constants.

src/pages/calendar/index.tsx (2)

15-17: LGTM! Clean dev mode detection.

Using the router query parameter to enable dev mode is appropriate and follows the pattern seen elsewhere in the codebase.


163-167: LGTM! Safe type handling.

The type guard ensures onDateChange only receives a valid Date instance, preventing potential runtime errors.

@@ -0,0 +1,42 @@
import { api } from './api';

export interface LogEntry {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • any specific reason we are using interface over type

const [displayList, setDisplayList] = useState<userDataType[]>([]);
const [data, setData] = useState([]);
const [data, setData] = useState<
Array<{ userId: string; data: LOG_DATA[] }>
Copy link
Contributor

Choose a reason for hiding this comment

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

define it type please

  • type UserLogData = Array<{ userId: string; data: LOG_DATA[] }>;

Comment on lines 65 to 82
useEffect(() => {
if (userData?.users) {
const users: userDataType[] = userData.users;
const filteredUsers: userDataType[] = users.filter(
(user: userDataType) => !user.incompleteUserDetails
);
const logData: any = filteredUsers.map((user: userDataType) => {
const log = logs[Math.floor(Math.random() * 4)];
return {
data: log,
userId: user.id,
};
});
const logData: Array<{ userId: string; data: LOG_DATA[] }> =
filteredUsers.map((user: userDataType) => {
const log = logs[Math.floor(Math.random() * 4)];
return {
data: log,
userId: user.id,
};
});
setData(logData);
setUsersList(filteredUsers);
}
}, [isLoading, userData]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at this file, it seems that we’re currently fetching all users from the database and then filtering them locally. Instead of doing that, I’d suggest using the user search API to fetch users directly based on their type.

For example, if we have 200 active users in the database but the getAllUsers only returns 100 users due to pagination, we might never find the intended user. Using the search API will make this process more efficient and reliable.

Comment on lines +73 to +74
const log = logs[Math.floor(Math.random() * 4)];
return {
Copy link
Contributor

Choose a reason for hiding this comment

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

also what is this math.random doing here

Copy link
Contributor

Choose a reason for hiding this comment

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

  • this search field doing so much ideally we should just search the user as the name suggested and pass to parent component

Comment on lines +26 to +47

const MONTHS = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];

export const formatTimestampToDate = (timestamp: number): string => {
const date = new Date(timestamp);
return `${
MONTHS[date.getMonth()]
} ${date.getDate()}, ${date.getFullYear()}`;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

  • since we already have moment then we can just do this

export const formatTimestampToDate = (timestamp: number): string => {
return moment(timestamp).format('MMM D, YYYY');
};


const [message, setMessage]: any = useState(null);
const [loading, setLoading]: any = useState(false);
const [selectedDate, onDateChange] = useState<Date>(new Date());
Copy link
Contributor

Choose a reason for hiding this comment

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

  • follow React convention for naming state

if (event.currentTarget.classList.contains('OOO')) {
setMessage(
`${selectedUser.username} is OOO on ${value.getDate()}-${
`${selectedUser?.username} is OOO on ${value.getDate()}-${
Copy link
Contributor

Choose a reason for hiding this comment

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

  • this piece of code ${value.getDate()}-${MONTHS[value.getMonth()]}-${value.getFullYear()} is used in around 3 4 places in this file , can we please make a small util function and reuse it

if (date.getDay() === 0) return 'sunday';
return processedData[0] ? processedData[0][date.getTime()] : null;

if (processedData[2].has(date.getTime())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

where is this processedData[2] , like what is the point of creating map


const oooEntries = processedData[2].get(value.getTime());
if (oooEntries) {
const message = formatOOODayMessage(
Copy link
Contributor

Choose a reason for hiding this comment

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

  • nit use different name for variable, we already have a state variable with name message

import { LogEntry } from '@/app/services/logsApi';

interface LOG_DATA {
export interface LOG_DATA {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • can we use type if possible

logsData: LogEntry[]
): [Map<number, OOOEntry[]>, Map<number, string>] => {
const dictWithOOOEntries = new Map<number, OOOEntry[]>();
const dictWithTask = new Map<number, string>();
Copy link
Contributor

Choose a reason for hiding this comment

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

  • we just define this variable and return it but never assign it something is it intentional

if (!itemId) {
return [{}, {}];
return [new Map(), new Map(), new Map()];
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • I think we can remove else condition as we are doing early return in the if case

Comment on lines +106 to +112
oooEntries.forEach((entries, dateTimestamp) => {
dictWithOOOEntries.set(dateTimestamp, entries);
});

oooEntries.forEach((_, dateTimestamp) => {
dictWithStatus.set(dateTimestamp, 'OOO');
});
Copy link
Contributor

Choose a reason for hiding this comment

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

can we combine both in one loop ?

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.

Make Status Site Calendar Functional with User Activity Data

4 participants