8000 ENG-1399 - Coco JR solution guide load improvements by adamkecskes · Pull Request #7832 · codecombat/codecombat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ENG-1399 - Coco JR solution guide load improvements #7832

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

Merged
merged 1 commit into from
Nov 19, 2024

Conversation

adamkecskes
Copy link
Collaborator
@adamkecskes adamkecskes commented Nov 15, 2024
  • don't show all solutions, just for the selected levels
  • nest junior practice levels under parent level
    guide

Summary by CodeRabbit

  • New Features

    • Enhanced English localization with new strings for AI integration, Roblox functionalities, and clearer user guidance.
    • Added functionality to show or hide practice levels, improving user interface flexibility.
    • Introduced buttons for toggling visibility of practice levels, tailored for junior teachers.
  • Style

    • New styles added for practice levels and visibility controls, enhancing layout and user interaction.
  • Bug Fixes

    • Improved logic for displaying course levels and resources, ensuring appropriate visibility based on user roles.

Copy link
Contributor
coderabbitai bot commented Nov 15, 2024

Walkthrough

The changes in this pull request involve extensive modifications to localization strings in app/locale/en.js, introducing new features related to AI integration and Roblox functionalities, as well as enhancing user interaction prompts. Additionally, new styling rules are added in app/styles/teachers/teacher-course-solution-view.sass for better layout and visibility of practice levels. The teacher-course-solution-view.pug template is updated to improve the rendering logic for course levels, particularly for junior teachers. The TeacherCourseSolutionView.js class is modified to include new event handlers for toggling practice levels and filtering displayed levels.

Changes

File Path Change Summary
app/locale/en.js Extensive modifications to localization strings, adding new strings for modal, parents, roblox, ai, and hackstack. New methods show_practice_levels and hide_practice_levels added.
app/styles/teachers/teacher-course-solution-view.sass New styles added for .practice-levels, .show-level-data.selected, and .show-practice-levels-button. Hover state for .small defined.
app/templates/teachers/teacher-course-solution-view.pug Enhanced rendering logic for course levels with new conditional checks for junior teachers and a button to toggle practice levels.
app/views/teachers/TeacherCourseSolutionView.js New event handlers onClickShowPracticeLevels and onClickShowLevelData added. Properties shownLevelModels and isJunior introduced.

Possibly related PRs

Suggested reviewers

  • mrfinch

🐰 In the code, we hop and play,
With strings and styles, we pave the way.
New features bloom, like flowers in spring,
Toggling levels, oh what joy they bring!
So let’s celebrate this code we share,
A rabbit’s delight, with love and care! 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

warning eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.
warning eslint > @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
warning eslint > @humanwhocodes/config-array > @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
warning eslint > file-entry-cache > flat-cache > rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
warning eslint > file-entry-cache > flat-cache > rimraf > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning eslint > file-entry-cache > flat-cache > rimraf > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning eslint-plugin-script-tags@0.5.0: Now published as @mapbox/eslint-plugin-script-tags
warning blockly > jsdom > abab@2.0.6: Use your platform's native atob() and btoa() methods instead
warning blockly > jsdom > data-urls > abab@2.0.6: Use your platform's native atob() and btoa() methods instead
warning blockly > jsdom > domexception@4.0.0: Use your platform's native DOMException instead
warning treema > express > mkdirp@0.3.3: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
warning treema > express > connect@2.7.2: connect 2.x series is deprecated
warning treema > express > connect > formidable@1.0.11: Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau
warning vue@2.7.10: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.
warning jasmine > glob@3.2.11: Glob versions prior to v9 are no longer supported
warning jasmine > glob > minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
warning karma > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning karma > rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
warning karma > socket.io > debug@4.1.1: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (debug-js/debug#797)
warning karma > tmp > rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
warning karma > socket.io > engine.io > debug@4.1.1: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (debug-js/debug#797)
warning karma > socket.io > socket.io-parser > debug@4.1.1: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (debug-js/debug#797)
warning pug > pug-filters > constantinople > babel-types > babel-runtime > core-js@2.6.12: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning standard > eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options.
warning @babel/plugin-proposal-optional-chaining@7.21.0: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
error treema@0.0.0: The engine "node" is incompatible with this module. Expected version "0.8.x". Got "22.9.0"
error Found incompatible module.


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

🧹 Outside diff range and nitpick comments (6)
app/styles/teachers/teacher-course-solution-view.sass (3)

5-7: Consider adding hover state for better interactivity

The selected state styling provides clear visual feedback. Consider adding a hover state for better user interaction.

 .show-level-data.selected
   font-weight: bold
   color: black
+.show-level-data:hover:not(.selected)
+  color: #666

8-12: Add cursor pointer for better interactivity

The button styling is clean and consistent. Consider adding cursor: pointer for better user interaction feedback.

 .show-practice-levels-button
   margin-left: 15px
   display: none
   border: none
   padding: 0 5px
+  cursor: pointer

13-14: Consider adding transition for smoother appearance

The hover-triggered visibility is a good UI pattern. Consider adding a transition for smoother appearance/disappearance.

 .show-practice-levels-button
   margin-left: 15px
   display: none
   border: none
   padding: 0 5px
+  opacity: 0
+  transition: opacity 0.2s ease-in-out
 .small:hover > .show-practice-levels-button
-  display: inline-block
+  display: inline-block
+  opacity: 1
app/views/teachers/TeacherCourseSolutionView.js (1)

151-152: Consider initialization improvements

The initialization of new properties could be more robust:

  1. Consider moving shownLevelModels initialization to constructor
  2. Add validation for course ID comparison
 constructor (options, courseID, language) {
   super(...arguments)
   this.courseID = courseID
   this.language = language
   this.isWebDev = [utils.courseIDs.WEB_DEVELOPMENT_2].includes(this.courseID)
+  this.shownLevelModels = []
+  this.isJunior = Boolean(this.courseID) && this.courseID === utils.courseIDs.JUNIOR
   this.callOz = !!utils.getQueryVariable('callOz')
   // ... rest of constructor
 }

 onLoaded () {
   this.paidTeacher = this.paidTeacher || this.prepaids.find(p => ['course', 'starter_license'].includes(p.get('type')) && (p.get('maxRedeemers') > 0))
   this.listenTo(me, 'change:preferredLanguage', this.updateLevelData)
   this.levels = new Levels(this.getGameContentAsLevels())
-  this.shownLevelModels = []
-  this.isJunior = this.courseID === utils.courseIDs.JUNIOR
   store.dispatch('gameContent/generateLevelNumberMap', { campaignId: this.campaignId, language: this.language })
     .then(() => {
app/templates/teachers/teacher-course-solution-view.pug (1)

55-55: Specify button type to prevent unintended form submissions

Add the type="button" attribute to the button element to prevent it from acting as a submit button in some browsers, which could cause unexpected behavior.

Apply this diff:

- button.show-practice-levels-button(data-slug=`${level.get('slug')}`)
+ button.show-practice-levels-button(type="button" data-slug=`${level.get('slug')}`)
app/locale/en.js (1)

Line range hint 4-18: Consider adding a comment to explain the purpose of this object.

While the object structure and syntax look correct, adding a brief comment at the top explaining what this translation object is used for would help with code readability and maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cac00b4 and 00e087a.

📒 Files selected for processing (4)
  • app/locale/en.js (1 hunks)
  • app/styles/teachers/teacher-course-solution-view.sass (1 hunks)
  • app/templates/teachers/teacher-course-solution-view.pug (1 hunks)
  • app/views/teachers/TeacherCourseSolutionView.js (4 hunks)
🔇 Additional comments (6)
app/styles/teachers/teacher-course-solution-view.sass (1)

2-3: LGTM: Practice levels indentation

The left margin creates a clear visual hierarchy for nested practice levels, consistent with the existing spacing patterns.

app/views/teachers/TeacherCourseSolutionView.js (3)

35-37: LGTM: Event handlers properly defined

The new event handlers follow the established pattern and are correctly bound to their respective UI elements.


276-276: LGTM: Clean destructuring syntax

The destructuring syntax change is a clean improvement to the code readability.


48-60: Verify integration with existing level selection logic

Let's verify that the new level filtering logic integrates correctly with existing course structure.

✅ Verification successful

Let me gather more information about the template usage and related components since the previous pug search failed.


Based on the gathered information, I can now generate the final response:

Level filtering implementation is correctly integrated

The implementation aligns well with existing level filtering patterns in the codebase:

  • The shownLevelModels state is properly initialized and only used within this view
  • Level filtering logic follows similar patterns used in other components (BaseAIJunior, BaseStudentAssessments)
  • The view handles both regular course solutions and campaign mode through dedicated routes
  • No conflicts found with other level selection mechanisms
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify integration points for level filtering

# Check for potential conflicts with existing level selection logic
rg -A 5 "shownLevelModels|showPracticeLevelsForSlug" --type js

# Look for related template conditionals
rg "v-if.*shownLevelModels|v-show.*showPracticeLevelsForSlug" --type pug

# Check for any existing level filtering methods that might conflict
ast-grep --pattern 'function $_($$_) { 
  $$$
  filter($$$)
  $$$
}'

Length of output: 2076


Script:

#!/bin/bash
# Search for template files with different extensions
fd -e jade -e vue -e html . -x rg -l "shownLevelModels|showPracticeLevelsForSlug" {}

# Check for related component initialization and state management
rg -A 5 "TeacherCourseSolutionView" --type js

# Look for related level filtering logic in the codebase
rg -A 3 "levels\.models.*filter" --type js

Length of output: 6306

app/templates/teachers/teacher-course-solution-view.pug (1)

68-68: Ensure view.shownLevelModels is correctly initialized

By iterating over view.shownLevelModels, confirm that this collection is properly populated with all the necessary levels. Verify that no levels are unintentionally omitted due to the new filtering logic, especially after toggling practice levels.

To verify the initialization of view.shownLevelModels, consider examining where it is set and ensuring it includes all expected levels based on user interactions.

app/locale/en.js (1)

Line range hint 1-2: Looks good!

The module exports syntax is correct.

Comment on lines +55 to +60
onClickShowLevelData (e) {
const levelData = $(e.target).closest('.show-level-data')
const slug = $(levelData[0]).data('slug')
this.shownLevelModels = this.levels.models.filter(l => l.get('slug') === slug)
this.render()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and optimize performance

The level data filtering implementation needs improvement:

  1. Add error handling for invalid slug
  2. Consider caching filtered results to avoid repeated filtering
 onClickShowLevelData (e) {
   const levelData = $(e.target).closest('.show-level-data')
   const slug = $(levelData[0]).data('slug')
+  if (!slug) {
+    console.error('Invalid level slug')
+    return
+  }
+  // Cache filtered results using slug as key
+  if (!this.levelModelCache) this.levelModelCache = {}
+  if (!this.levelModelCache[slug]) {
+    this.levelModelCache[slug] = this.levels.models.filter(l => l.get('slug') === slug)
+  }
-  this.shownLevelModels = this.levels.models.filter(l => l.get('slug') === slug)
+  this.shownLevelModels = this.levelModelCache[slug]
   this.render()
 }
📝 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.

Suggested change
onClickShowLevelData (e) {
const levelData = $(e.target).closest('.show-level-data')
const slug = $(levelData[0]).data('slug')
this.shownLevelModels = this.levels.models.filter(l => l.get('slug') === slug)
this.render()
}
onClickShowLevelData (e) {
const levelData = $(e.target).closest('.show-level-data')
const slug = $(levelData[0]).data('slug')
if (!slug) {
console.error('Invalid level slug')
return
}
// Cache filtered results using slug as key
if (!this.levelModelCache) this.levelModelCache = {}
if (!this.levelModelCache[slug]) {
this.levelModelCache[slug] = this.levels.models.filter(l => l.get('slug') === slug)
}
this.shownLevelModels = this.levelModelCache[slug]
this.render()
}

Comment on lines +48 to +53
8000
onClickShowPracticeLevels (e) {
const button = $(e.target).closest('.show-practice-levels-button')
const shown = this.showPracticeLevelsForSlug === button.data().slug
this.showPracticeLevelsForSlug = shown ? null : button.data().slug
this.render()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add null check and analytics tracking

The practice levels toggle implementation could be more robust:

  1. Add null check for button.data()
  2. Add analytics tracking for UX insights
 onClickShowPracticeLevels (e) {
   const button = $(e.target).closest('.show-practice-levels-button')
+  const buttonData = button.data()
+  if (!buttonData || !buttonData.slug) return
-  const shown = this.showPracticeLevelsForSlug === button.data().slug
-  this.showPracticeLevelsForSlug = shown ? null : button.data().slug
+  const shown = this.showPracticeLevelsForSlug === buttonData.slug
+  this.showPracticeLevelsForSlug = shown ? null : buttonData.slug
+  window.tracker?.trackEvent('Teacher Show Practice Levels', {
+    shown: !shown,
+    slug: buttonData.slug
+  })
   this.render()
 }
📝 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.

Suggested change
onClickShowPracticeLevels (e) {
const button = $(e.target).closest('.show-practice-levels-button')
const shown = this.showPracticeLevelsForSlug === button.data().slug
this.showPracticeLevelsForSlug = shown ? null : button.data().slug
this.render()
}
onClickShowPracticeLevels (e) {
const button = $(e.target).closest('.show-practice-levels-button')
const buttonData = button.data()
if (!buttonData || !buttonData.slug) return
const shown = this.showPracticeLevelsForSlug === buttonData.slug
this.showPracticeLevelsForSlug = shown ? null : buttonData.slug
window.tracker?.trackEvent('Teacher Show Practice Levels', {
shown: !shown,
slug: buttonData.slug
})
this.render()
}

Comment on lines +53 to +54
- let practiceLevels = view.levels.models.filter(l => l.get('practice') && l.get('name').match(level.get('name')))
if practiceLevels.length > 0
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential issue with matching level names using match

The use of l.get('name').match(level.get('name')) may lead to incorrect matching if level names contain similar substrings or special characters. This could result in practice levels being associated with incorrect parent levels. Consider using a stricter comparison method, such as comparing unique identifiers or using exact string equality.

Apply this diff to fix the issue:

- let practiceLevels = view.levels.models.filter(l => l.get('practice') &&  l.get('name').match(level.get('name')))
+ let practiceLevels = view.levels.models.filter(l => l.get('practice') && l.get('original') === level.get('original'))

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +2869 to +2870
show_practice_levels: 'Show Practice Levels',
hide_practice_levels: 'Hide Practice Levels',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Inconsistent indentation detected.

The indentation for these two lines does not match the indentation level of the surrounding code block. Make sure to use consistent indentation for improved code readability.

Apply this diff to fix the indentation:

-      show_practice_levels: 'Show Practice Levels',
-      hide_practice_levels: 'Hide Practice Levels',
+    show_practice_levels: 'Show Practice Levels',
+    hide_practice_levels: 'Hide Practice Levels',

Committable suggestion skipped: line range outside the PR's diff.

@mrfinch mrfinch merged commit f1d04db into master Nov 19, 2024
2 checks passed
@mrfinch mrfinch deleted the adamk/coco-jr-solution-guide-load-improvements branch November 19, 2024 06:17
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
0