Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(apps/frontend-manage): make sure that runtime counter on live quiz cockpit does not trigger re-rendering of timeline #4364

Merged
merged 2 commits into from
Nov 8, 2024

Conversation

sjschlapbach
Copy link
Member

@sjschlapbach sjschlapbach commented Nov 8, 2024

Summary by CodeRabbit

  • New Features

    • Introduced the RuntimeCounter component to display session runtime.
    • Enhanced SessionTimeline to utilize RuntimeCounter for runtime display.
    • Improved session management and user feedback mechanisms in the Cockpit component.
  • Bug Fixes

    • Updated error handling logic for session data fetching to improve user feedback.
  • Chores

    • Streamlined GitHub Actions workflows by removing path restrictions for pull request triggers.

…z cockpit does not trigger re-rendering of timeline
@sjschlapbach sjschlapbach marked this pull request as ready for review November 8, 2024 11:46
Copy link

aviator-app bot commented Nov 8, 2024

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This PR was merged manually (without Aviator). Merging manually can negatively impact the performance of the queue. Consider using Aviator next time.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

Copy link

coderabbitai bot commented Nov 8, 2024

📝 Walkthrough

Walkthrough

The pull request modifies GitHub Actions workflow configurations for the test grading and GraphQL packages by removing the paths specification under the pull_request trigger, allowing workflows to trigger on all pull requests for specified branches. Additionally, it introduces a new React component, RuntimeCounter, which calculates and displays session runtime in the frontend application, replacing inline runtime calculations in the SessionTimeline component. The Cockpit component also sees updates to session management and user feedback handling.

Changes

File Path Change Summary
.github/workflows/test-grading.yml Removed paths specification under pull_request trigger, allowing broader workflow triggering. push trigger remains unchanged. Job configuration for testing remains intact.
.github/workflows/test-graphql.yml Removed paths specification under pull_request trigger, allowing broader workflow triggering. push trigger remains unchanged. Job configuration for testing remains intact.
apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx Added a new React component RuntimeCounter that calculates and displays session runtime using dayjs. Manages state and updates every second.
apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx Modified to import and utilize RuntimeCounter instead of inline runtime calculations. Removed calculateRuntime function and related logic. Simplified state management by delegating runtime display to RuntimeCounter.
apps/frontend-manage/src/pages/sessions/[id]/cockpit.tsx Updated Cockpit component for improved session block handling and user feedback. Clarified usage of mutations and added loading state management. Adjusted error handling logic and updated props for SessionTimeline and AudienceInteraction.

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d07ab42 and dfc2f99.

📒 Files selected for processing (5)
  • .github/workflows/test-grading.yml (0 hunks)
  • .github/workflows/test-graphql.yml (0 hunks)
  • apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx (1 hunks)
  • apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx (2 hunks)
  • apps/frontend-manage/src/pages/sessions/[id]/cockpit.tsx (0 hunks)
💤 Files with no reviewable changes (3)
  • .github/workflows/test-grading.yml
  • .github/workflows/test-graphql.yml
  • apps/frontend-manage/src/pages/sessions/[id]/cockpit.tsx
🔇 Additional comments (4)
apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx (2)

1-8: LGTM! Clean imports and proper dayjs setup.

The imports are well-organized and the dayjs plugin setup is correctly implemented.


1-49: Verify impact on timeline re-rendering

The implementation looks good for preventing timeline re-renders, but let's verify the integration.

✅ Verification successful

Let me gather more information about the SessionTimeline component to verify the re-rendering behavior.


Let me try a different approach to check the SessionTimeline implementation.


Based on the SessionTimeline implementation, I can now provide the final response:

✅ Runtime counter implementation effectively prevents timeline re-renders

The RuntimeCounter component is properly isolated and integrated in SessionTimeline:

  • It maintains its own state and update cycle independent of the parent
  • The parent only passes the startedAt prop which is stable
  • The interval cleanup is correctly implemented to prevent memory leaks
  • The component is rendered in a position that won't trigger unnecessary parent re-renders
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check how SessionTimeline uses RuntimeCounter
rg -l "SessionTimeline" apps/frontend-manage/src
rg -A 5 "RuntimeCounter" apps/frontend-manage/src/components/sessions/

Length of output: 2483


Script:

#!/bin/bash
# Check SessionTimeline implementation for potential re-rendering issues
ast-grep --pattern 'function SessionTimeline($$$) {
  $$$
}'

# Check if there are any other components using RuntimeCounter
rg "RuntimeCounter" --type ts --type tsx

Length of output: 131


Script:

#!/bin/bash
# Check the full implementation of SessionTimeline
cat apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx

# Check for RuntimeCounter usage with proper file type
rg "RuntimeCounter" -t typescript -t typescriptreact

Length of output: 10804

apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx (2)

17-17: LGTM: Clean separation of runtime display logic

The addition of RuntimeCounter import aligns with the PR objective of preventing timeline re-renders by extracting runtime calculation logic into a separate component.


Line range hint 1-276: Verify complete removal of runtime calculation logic

Let's ensure no runtime calculation logic remains in the timeline component.

✅ Verification successful

Let me check the RuntimeCounter implementation to ensure complete isolation of runtime logic.


Runtime calculation logic successfully isolated

The verification confirms that:

  • All runtime calculation logic has been moved to the RuntimeCounter component
  • No runtime-related state or calculations remain in SessionTimeline
  • RuntimeCounter properly encapsulates the timer functionality with its own state management
  • The only connection between components is the startedAt prop passed to RuntimeCounter
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining runtime calculation code in the timeline component

# Test 1: Search for dayjs usage related to runtime
echo "Checking for dayjs runtime calculations..."
rg -i "dayjs.*runtime|runtime.*dayjs" apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx

# Test 2: Search for setInterval related to runtime
echo "Checking for runtime interval updates..."
rg "setInterval.*runtime|runtime.*setInterval" apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx

# Test 3: Verify RuntimeCounter implementation
echo "Checking RuntimeCounter implementation..."
rg -l "RuntimeCounter" apps/frontend-manage/src/components/sessions/cockpit/

Length of output: 735


Script:

#!/bin/bash
# Check RuntimeCounter implementation
echo "RuntimeCounter implementation:"
cat apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx

# Check for any state management or runtime calculations in SessionTimeline
echo -e "\nChecking SessionTimeline for runtime state:"
rg "const.*runtime|runtime.*state|useEffect.*runtime" apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx

Length of output: 1868


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

sonarqubecloud bot commented Nov 8, 2024

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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx (1)

24-47: Add TypeScript interfaces and error handling

The component could benefit from better type safety and error handling.

Consider these improvements:

+interface RuntimeCounterProps {
+  startedAt?: string
+}
+
-function RuntimeCounter({ startedAt }: { startedAt?: string }) {
+function RuntimeCounter({ startedAt }: RuntimeCounterProps) {
+  if (!startedAt) {
+    return null
+  }
+
   const [runtime, setRuntime] = useState(calculateRuntime({ startedAt }))
   const startingTime = runtime.includes('d')
     ? dayjs(startedAt).format('DD.MM HH:mm:ss')
     : dayjs(startedAt).format('HH:mm:ss')

Also consider adding a loading state or error boundary for better user experience.

apps/frontend-manage/src/components/sessions/cockpit/SessionTimeline.tsx (2)

Line range hint 63-91: LGTM: Clean state management

The useEffect hook properly manages session state transitions without being affected by runtime updates. This separation ensures that timeline state updates only occur when block statuses change, not on every runtime tick.

Consider memoizing the blocks.find() and blocks.every() operations if the blocks array is large, though this is likely unnecessary for typical quiz scenarios.


110-112: Consider flex layout optimization

The RuntimeCounter integration looks good, but the flex layout could be improved to prevent potential layout shifts during runtime updates.

Consider adding a minimum width to prevent layout shifts:

-          <RuntimeCounter startedAt={startedAt} />
+          <div className="min-w-[120px]">
+            <RuntimeCounter startedAt={startedAt} />
+          </div>
🛑 Comments failed to post (2)
apps/frontend-manage/src/components/sessions/cockpit/RuntimeCounter.tsx (2)

30-35: ⚠️ Potential issue

Fix useEffect dependencies to prevent unnecessary interval resets

The current dependency array includes runtime which causes the interval to be reset every second unnecessarily.

Apply this fix:

   useEffect(() => {
     const currentRuntime = setInterval(() => {
       setRuntime(calculateRuntime({ startedAt }))
     }, 1000)
     return () => clearInterval(currentRuntime)
-  }, [runtime, startedAt])
+  }, [startedAt])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  useEffect(() => {
    const currentRuntime = setInterval(() => {
      setRuntime(calculateRuntime({ startedAt }))
    }, 1000)
    return () => clearInterval(currentRuntime)
  }, [startedAt])

9-22: 🛠️ Refactor suggestion

Add error handling and improve code robustness

The function needs better error handling and could be optimized.

Consider these improvements:

-const calculateRuntime = ({ startedAt }: { startedAt?: string }) => {
+const calculateRuntime = (startedAt?: string) => {
+  if (!startedAt) {
+    return '00:00:00'
+  }
+
   const start = dayjs(startedAt)
+  if (!start.isValid()) {
+    return '00:00:00'
+  }
+
   const duration = dayjs.duration(dayjs().diff(start))

   const days = duration.days()
-  const hours = `0${duration.hours()}`.slice(-2)
-  const minutes = `0${duration.minutes()}`.slice(-2)
-  const seconds = `0${duration.seconds()}`.slice(-2)
+  const hours = duration.hours().toString().padStart(2, '0')
+  const minutes = duration.minutes().toString().padStart(2, '0')
+  const seconds = duration.seconds().toString().padStart(2, '0')

   if (days > 0) {
     return `${days}d ${hours}:${minutes}:${seconds}`
   }
   return `${hours}:${minutes}:${seconds}`
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const calculateRuntime = (startedAt?: string) => {
  if (!startedAt) {
    return '00:00:00'
  }

  const start = dayjs(startedAt)
  if (!start.isValid()) {
    return '00:00:00'
  }

  const duration = dayjs.duration(dayjs().diff(start))

  const days = duration.days()
  const hours = duration.hours().toString().padStart(2, '0')
  const minutes = duration.minutes().toString().padStart(2, '0')
  const seconds = duration.seconds().toString().padStart(2, '0')

  if (days > 0) {
    return `${days}d ${hours}:${minutes}:${seconds}`
  }
  return `${hours}:${minutes}:${seconds}`
}

Copy link

cypress bot commented Nov 8, 2024

klicker-uzh    Run #3611

Run Properties:  status check passed Passed #3611  •  git commit 85dbb81537 ℹ️: Merge dfc2f99183938f02998cf0a136a81027dec9d069 into d07ab421ce0adb84343385d98437...
Project klicker-uzh
Branch Review fix-live-quiz-timer
Run status status check passed Passed #3611
Run duration 11m 43s
Commit git commit 85dbb81537 ℹ️: Merge dfc2f99183938f02998cf0a136a81027dec9d069 into d07ab421ce0adb84343385d98437...
Committer Julius Schlapbach
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 140
View all changes introduced in this branch ↗︎

@sjschlapbach sjschlapbach merged commit d82f896 into v3 Nov 8, 2024
14 checks passed
@sjschlapbach sjschlapbach deleted the fix-live-quiz-timer branch November 8, 2024 12:10
Copy link

cypress bot commented Nov 8, 2024

klicker-uzh    Run #3612

Run Properties:  status check passed Passed #3612  •  git commit d82f89621a: fix(apps/frontend-manage): make sure that runtime counter on live quiz cockpit d...
Project klicker-uzh
Branch Review v3
Run status status check passed Passed #3612
Run duration 11m 15s
Commit git commit d82f89621a: fix(apps/frontend-manage): make sure that runtime counter on live quiz cockpit d...
Committer Julius Schlapbach
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 140
View all changes introduced in this branch ↗︎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant