-
Notifications
You must be signed in to change notification settings - Fork 152
JS to TS : simulator/src/tutorial.ts #438
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
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces TypeScript files to the simulator source directory, focusing on enhancing the project setup, tutorial system, and project management. New files like Changes
Assessment against linked issues
Sequence DiagramsequenceDiagram
participant User
participant Setup
participant ProjectData
participant Tutorial
User->>Setup: Initiate Application
Setup->>ProjectData: Fetch Project Data
Setup->>Setup: Configure Environment
Setup->>Setup: Resize Canvas
Setup->>Tutorial: Check Tutorial Status
Tutorial-->>User: Show Tour Guide
Poem
✨ Finishing Touches
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
✅ Deploy Preview for circuitverse ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (3)
src/simulator/src/tutorials.ts (1)
17-100
: Consider standardizing element selectors.The tour steps use a mix of ID selectors (
#guide_1
,#tabsBar
) and class selectors (.guide_2
,.quick-btn
). Consider standardizing the approach to use either IDs or classes consistently for better maintainability.src/simulator/src/data/project.ts (1)
173-174
: Use URL constructor for better URL handling.The URL construction could be improved using the URL API for better robustness:
- const baseUrl = window.location.origin !== 'null' ? window.location.origin : 'http://localhost:4000' - window.location.assign(`${baseUrl}/simulatorvue/`) + const baseUrl = new URL(window.location.origin !== 'null' ? window.location.origin : 'http://localhost:4000'); + baseUrl.pathname = '/simulatorvue/'; + window.location.assign(baseUrl.toString());src/simulator/src/setup.ts (1)
99-124
: Modernize jQuery usage.Consider replacing jQuery fade effects with native JavaScript or CSS transitions:
- ($('.loadingIcon') as any).fadeOut(); + const loadingIcon = document.querySelector('.loadingIcon'); + if (loadingIcon) { + loadingIcon.classList.add('fade-out'); + loadingIcon.addEventListener('transitionend', () => { + loadingIcon.style.display = 'none'; + }); + }Add corresponding CSS:
.fade-out { opacity: 0; transition: opacity 0.3s ease-out; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/components/Panels/ElementsPanel/ElementsPanel.vue
(3 hunks)src/simulator/src/data/project.ts
(2 hunks)src/simulator/src/setup.ts
(1 hunks)src/simulator/src/tutorials.ts
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/simulator/src/setup.ts
[error] 38-38: Can't assign DPR because it's a constant
This is where the variable is defined as constant
Unsafe fix: Replace const with let if you assign it to a new value.
(lint/correctness/noConstAssign)
🔇 Additional comments (2)
src/simulator/src/tutorials.ts (1)
3-15
: LGTM! Well-structured interfaces.The interfaces
Popover
andTourStep
are well-defined with clear types and optional properties.src/components/Panels/ElementsPanel/ElementsPanel.vue (1)
128-131
: Verify styling dependencies.The code uses Bootstrap-like classes (
overflow-hidden
,text-nowrap
,d-inline-block
). Please ensure these classes are properly defined in your styling system or consider using Vue's native class bindings:Alternative approach using Vue's native class bindings:
- <div class="overflow-hidden text-nowrap position-relative"> - <p class=" d-inline-block">{{ element.name }}</p> + <div :class="$style.elementName"> + <p>{{ element.name }}</p>Add scoped styles:
<style module> .elementName { overflow: hidden; white-space: nowrap; position: relative; } .elementName p { display: inline-block; } </style>✅ Verification successful
Bootstrap utility classes are properly configured ✓
The codebase has Bootstrap v4.6.1 properly installed as a dependency, so the utility classes used in the component are valid and will work as expected.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for Bootstrap or similar CSS framework dependencies rg -l "bootstrap|tailwind" --type=json package.jsonLength of output: 66
Script:
#!/bin/bash # Display package.json content to check actual dependencies cat package.jsonLength of output: 2288
export function showTourGuide(): void { | ||
document.querySelector('.draggable-panel .maximize')?.dispatchEvent(new Event('click')); | ||
animatedTourDriver.defineSteps(tour); | ||
animatedTourDriver.start(); | ||
localStorage.setItem('tutorials_tour_done', 'true'); | ||
} |
There was a problem hiding this comment.
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 for panel maximization.
The showTourGuide
function should handle cases where the panel element is not found or the click event fails.
export function showTourGuide(): void {
- document.querySelector('.draggable-panel .maximize')?.dispatchEvent(new Event('click'));
+ const panel = document.querySelector('.draggable-panel .maximize');
+ if (!panel) {
+ console.error('Panel maximize button not found');
+ return;
+ }
+ try {
+ panel.dispatchEvent(new Event('click'));
+ } catch (error) {
+ console.error('Failed to maximize panel:', error);
+ return;
+ }
animatedTourDriver.defineSteps(tour);
animatedTourDriver.start();
localStorage.setItem('tutorials_tour_done', 'true');
}
📝 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.
export function showTourGuide(): void { | |
document.querySelector('.draggable-panel .maximize')?.dispatchEvent(new Event('click')); | |
animatedTourDriver.defineSteps(tour); | |
animatedTourDriver.start(); | |
localStorage.setItem('tutorials_tour_done', 'true'); | |
} | |
export function showTourGuide(): void { | |
const panel = document.querySelector('.draggable-panel .maximize'); | |
if (!panel) { | |
console.error('Panel maximize button not found'); | |
return; | |
} | |
try { | |
panel.dispatchEvent(new Event('click')); | |
} catch (error) { | |
console.error('Failed to maximize panel:', error); | |
return; | |
} | |
animatedTourDriver.defineSteps(tour); | |
animatedTourDriver.start(); | |
localStorage.setItem('tutorials_tour_done', 'true'); | |
} |
// Not used currently | ||
export const tutorialWrapper = (): void => { | ||
const panelHighlight = new Driver(); | ||
document.querySelector('.panelHeader')?.addEventListener( | ||
'click', | ||
(e: MouseEvent) => { | ||
if (localStorage.getItem('tutorials') === 'next') { | ||
panelHighlight.highlight({ | ||
element: '#guide_1', | ||
showButtons: false, | ||
popover: { | ||
title: 'Here are the elements', | ||
description: | ||
'Select any element by clicking on it & then click anywhere on the grid to place the element.', | ||
position: 'right', | ||
offset: | ||
(e.target as HTMLElement).nextElementSibling?.clientHeight! + | ||
(e.target as HTMLElement).offsetTop - | ||
45, | ||
}, | ||
}); | ||
localStorage.setItem('tutorials', 'done'); | ||
} | ||
}, | ||
{ | ||
once: true, | ||
} | ||
); | ||
document.querySelector('.icon')?.addEventListener('click', () => { | ||
panelHighlight.reset(true); | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused code.
The tutorialWrapper
function is marked as "Not used currently". Consider removing it to maintain code cleanliness.
Simplify offset calculation.
The offset calculation is complex and hard to maintain:
- offset:
- (e.target as HTMLElement).nextElementSibling?.clientHeight! +
- (e.target as HTMLElement).offsetTop -
- 45,
+ offset: calculateOffset(e.target as HTMLElement),
Consider extracting it into a separate helper function for better readability and maintainability.
Committable suggestion skipped: line range outside the PR's diff.
// window.onbeforeunload = async function () { | ||
// if (projectSaved || embed) return | ||
|
||
if (!checkToSave()) return | ||
// if (!checkToSave()) return | ||
|
||
alert( | ||
'You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?' | ||
) | ||
// await confirmSingleOption( | ||
// 'You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?' | ||
// ) | ||
const data = await generateSaveData('Untitled') | ||
const stringData = JSON.stringify(data) | ||
localStorage.setItem('recover', stringData) | ||
// eslint-disable-next-line consistent-return | ||
return 'Are u sure u want to leave? Any unsaved changes may not be recoverable' | ||
} | ||
// alert( | ||
// 'You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?' | ||
// ) | ||
// // await confirmSingleOption( | ||
// // 'You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?' | ||
// // ) | ||
// const data = await generateSaveData('Untitled') | ||
// const stringData = JSON.stringify(data) | ||
// localStorage.setItem('recover', stringData) | ||
// // eslint-disable-next-line consistent-return | ||
// return 'Are u sure u want to leave? Any unsaved changes may not be recoverable' | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
🛠️ Refactor suggestion
Reconsider removing the page leave warning
While there is a recovery mechanism in place, removing the onbeforeunload
handler eliminates the primary way to prevent accidental data loss. The current recovery system only helps after the fact, but doesn't prevent users from accidentally navigating away with unsaved changes.
- Consider keeping or reimplementing the
onbeforeunload
handler to maintain better user experience - If removal is intentional, ensure users are clearly informed about the auto-recovery feature
- The commented code should still be removed from the codebase, but the functionality should be preserved
🔗 Analysis chain
Remove commented code.
Instead of keeping commented code, consider removing it entirely and preserving it in version control history if needed.
Verify impact on user experience.
The removal of the onbeforeunload
handler means users won't be warned about unsaved changes when leaving the page. Please confirm if this is intentional and if there are alternative measures to prevent data loss.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any other implementations of onbeforeunload or similar data loss prevention
rg -l "onbeforeunload|beforeunload|unload" --type ts --type vue
Length of output: 93
Script:
#!/bin/bash
# Search in TypeScript files
echo "Searching TypeScript files..."
rg -l "onbeforeunload|beforeunload|unload|unsaved|warning" --type ts
# Search in .vue files directly
echo "Searching Vue files..."
find . -name "*.vue" -type f -exec rg -l "onbeforeunload|beforeunload|unload|unsaved|warning" {} \;
# Search for save-related functionality
echo "Searching for save-related functionality..."
rg -l "saveProject|saveTo|autoSave" --type ts
find . -name "*.vue" -type f -exec rg -l "saveProject|saveTo|autoSave" {} \;
Length of output: 743
Script:
#!/bin/bash
# Check content of setup.ts for related functionality
echo "Content of setup.ts:"
rg -A 5 -B 5 "onbeforeunload|beforeunload|unload|unsaved|warning" src/simulator/src/setup.ts
# Also check the Vue components for context
echo "Content of relevant Vue components:"
find . -name "*.vue" -type f -exec rg -A 5 -B 5 "onbeforeunload|beforeunload|unload|unsaved|warning" {} \;
Length of output: 4640
const DPR = window.devicePixelRatio || 1; | ||
if (lightMode) { | ||
DPR = 1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix const reassignment of DPR.
The DPR variable is declared as const but reassigned, which is incorrect:
- const DPR = window.devicePixelRatio || 1;
- if (lightMode) {
- DPR = 1;
- }
+ let DPR = lightMode ? 1 : (window.devicePixelRatio || 1);
📝 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 DPR = window.devicePixelRatio || 1; | |
if (lightMode) { | |
DPR = 1; | |
} | |
let DPR = lightMode ? 1 : (window.devicePixelRatio || 1); |
🧰 Tools
🪛 Biome (1.9.4)
[error] 38-38: Can't assign DPR because it's a constant
This is where the variable is defined as constant
Unsafe fix: Replace const with let if you assign it to a new value.
(lint/correctness/noConstAssign)
function showTour(): void { | ||
if (!localStorage.tutorials_tour_done && !embed) { | ||
setTimeout(() => { | ||
showTourGuide(); | ||
}, 2000); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add cleanup for setTimeout.
The setTimeout should be cleaned up to prevent memory leaks:
function showTour(): void {
if (!localStorage.tutorials_tour_done && !embed) {
- setTimeout(() => {
+ const timeoutId = setTimeout(() => {
showTourGuide();
}, 2000);
+ // Add cleanup method to clear timeout
+ return () => clearTimeout(timeoutId);
}
}
Committable suggestion skipped: line range outside the PR's diff.
const width = document.getElementById('simulationArea')?.clientWidth! * DPR; | ||
let height; | ||
if (!embed) { | ||
height = | ||
(document.body.clientHeight - | ||
document.getElementById('toolbar')?.clientHeight!) * | ||
DPR; | ||
} else { | ||
height = document.getElementById('simulation')?.clientHeight! * DPR; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add null checks for DOM elements.
Replace non-null assertions with proper null checks:
- const width = document.getElementById('simulationArea')?.clientWidth! * DPR;
+ const simulationArea = document.getElementById('simulationArea');
+ if (!simulationArea) {
+ console.error('Simulation area not found');
+ return;
+ }
+ const width = simulationArea.clientWidth * DPR;
Committable suggestion skipped: line range outside the PR's diff.
Fixes #414
Describe the changes you have made in this PR -
Screenshots of the changes (If any) -
Note: Please check Allow edits from maintainers. if you would like us to assist in the PR.
Summary by CodeRabbit
New Features
Improvements
Changes