From b7ee90c8cf6b63fcd6b21f4e41eff33fa2f40cf3 Mon Sep 17 00:00:00 2001 From: ShinichiShi Date: Mon, 20 Oct 2025 20:18:56 +0530 Subject: [PATCH 1/3] refactor setup.js to ts --- src/simulator/src/{setup.js => setup.ts} | 83 ++++++++++++++++-------- src/simulator/src/types/setup.types.ts | 18 +++++ 2 files changed, 73 insertions(+), 28 deletions(-) rename src/simulator/src/{setup.js => setup.ts} (70%) create mode 100644 src/simulator/src/types/setup.types.ts diff --git a/src/simulator/src/setup.js b/src/simulator/src/setup.ts similarity index 70% rename from src/simulator/src/setup.js rename to src/simulator/src/setup.ts index 1f04977e6..ff394cc51 100644 --- a/src/simulator/src/setup.js +++ b/src/simulator/src/setup.ts @@ -25,6 +25,20 @@ import '../vendor/jquery-ui.min.css' import '../vendor/jquery-ui.min' import { confirmSingleOption } from '#/components/helpers/confirmComponent/ConfirmComponent.vue' import { getToken } from '#/pages/simulatorHandler.vue' +import { ProjectData } from './types/setup.types' +import { BackgroundArea } from './interface/backgroundArea' + +declare var DPR: number +declare var width: number +declare var height: number +declare var embed: boolean +declare var lightMode: boolean +interface PlotArea { + setup: () => void +} + +const typedBackgroundArea = backgroundArea as unknown as BackgroundArea +const typedPlotArea = plotArea as unknown as PlotArea /** * to resize window and setup things it @@ -32,36 +46,46 @@ import { getToken } from '#/pages/simulatorHandler.vue' * Also redraws the grid. * @category setup */ -export function resetup() { +export function resetup(): void { DPR = window.devicePixelRatio || 1 if (lightMode) { DPR = 1 } - width = document.getElementById('simulationArea').clientWidth * DPR + width = document.getElementById('simulationArea')!.clientWidth * DPR if (!embed) { + const toolbar = document.getElementById('toolbar') height = - (document.body.clientHeight - - document.getElementById('toolbar')?.clientHeight) * - DPR + (document.body.clientHeight - (toolbar?.clientHeight || 0)) * DPR } else { - height = document.getElementById('simulation').clientHeight * DPR + height = document.getElementById('simulation')!.clientHeight * DPR } // setup simulationArea and backgroundArea variables used to make changes to canvas. backgroundArea.setup() simulationArea.setup() // redraw grid dots() - document.getElementById('backgroundArea').style.height = - height / DPR + 100 + 'px' - document.getElementById('backgroundArea').style.width = - width / DPR + 100 + 'px' - document.getElementById('canvasArea').style.height = height / DPR + 'px' + const bgArea = document.getElementById('backgroundArea') + const canvasArea = document.getElementById('canvasArea') + + if (bgArea) { + bgArea.style.height = height / DPR + 100 + 'px' + bgArea.style.width = width / DPR + 100 + 'px' + } + + if (canvasArea) { + canvasArea.style.height = height / DPR + 'px' + } + simulationArea.canvas.width = width simulationArea.canvas.height = height - backgroundArea.canvas.width = width + 100 * DPR - backgroundArea.canvas.height = height + 100 * DPR + + if (typedBackgroundArea.canvas) { + typedBackgroundArea.canvas.width = width + 100 * DPR + typedBackgroundArea.canvas.height = height + 100 * DPR + } + if (!embed) { - plotArea.setup() + typedPlotArea.setup() } updateCanvasSet(true) update() // INEFFICIENT, needs to be deprecated @@ -79,13 +103,13 @@ window.addEventListener('orientationchange', resetup) // listener * function to setup environment variables like projectId and DPR * @category setup */ -function setupEnvironment() { +function setupEnvironment(): void { setupModules() const projectId = generateId() window.projectId = projectId updateSimulationSet(true) // const DPR = window.devicePixelRatio || 1 // unused variable - newCircuit('Main') + newCircuit('Main', undefined, false, false) window.data = {} resetup() setupCodeMirrorEnvironment() @@ -96,7 +120,7 @@ function setupEnvironment() { * @param {number} projectId The ID of the project to fetch data for * @category setup */ -async function fetchProjectData(projectId) { +async function fetchProjectData(projectId: number): Promise { try { const response = await fetch( `/api/v1/projects/${projectId}/circuit_data`, @@ -109,8 +133,8 @@ async function fetchProjectData(projectId) { } ) if (response.ok) { - const data = await response.json() - await load(data) + const data: ProjectData = await response.json() + await load(data as any) await simulationArea.changeClockTime(data.timePeriod || 500) $('.loadingIcon').fadeOut() } else { @@ -128,18 +152,21 @@ async function fetchProjectData(projectId) { * Improvement to eliminate delay caused by setTimeout in previous implementation revert if issues arise. * @category setup */ -async function loadProjectData() { +async function loadProjectData(): Promise { window.logixProjectId = window.logixProjectId ?? 0 if (window.logixProjectId !== 0) { $('.loadingIcon').fadeIn() await fetchProjectData(window.logixProjectId) } else if (localStorage.getItem('recover_login') && window.isUserLoggedIn) { // Restore unsaved data and save - const data = JSON.parse(localStorage.getItem('recover_login')) - await load(data) - localStorage.removeItem('recover') - localStorage.removeItem('recover_login') - await save() + const item = localStorage.getItem('recover_login') + if (item) { + const data = JSON.parse(item) + await load(data as any) + localStorage.removeItem('recover') + localStorage.removeItem('recover_login') + await save() + } } else if (localStorage.getItem('recover')) { // Restore unsaved data which didn't get saved due to error showMessage( @@ -153,8 +180,8 @@ async function loadProjectData() { * The tour is shown after a delay of 2 seconds. * @category setup */ -function showTour() { - if (!localStorage.tutorials_tour_done && !embed) { +function showTour(): void { + if (!localStorage.getItem('tutorials_tour_done') && !embed) { setTimeout(() => { showTourGuide() }, 2000) @@ -167,7 +194,7 @@ function showTour() { * loads the project data, and shows the tour guide. * @category setup */ -export function setup() { +export function setup(): void { setupEnvironment() if (!embed) { setupUI() diff --git a/src/simulator/src/types/setup.types.ts b/src/simulator/src/types/setup.types.ts new file mode 100644 index 000000000..ebdc88b63 --- /dev/null +++ b/src/simulator/src/types/setup.types.ts @@ -0,0 +1,18 @@ +declare global { + interface Window { + projectId: string; + data: Record; + logixProjectId: number; + isUserLoggedIn: boolean; + DPR: number; + width: number; + height: number; + embed: boolean; + lightMode: boolean; + } +} + +export interface ProjectData { + timePeriod?: number; + [key: string]: any; +} From f84df4a4e0830bb8e320b29a9b46f52af73bf4d8 Mon Sep 17 00:00:00 2001 From: ShinichiShi Date: Tue, 21 Oct 2025 01:03:07 +0530 Subject: [PATCH 2/3] apply coderabbit suggestion n fix errors --- src/simulator/src/setup.ts | 62 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/simulator/src/setup.ts b/src/simulator/src/setup.ts index ff394cc51..4ea4e5811 100644 --- a/src/simulator/src/setup.ts +++ b/src/simulator/src/setup.ts @@ -26,20 +26,11 @@ import '../vendor/jquery-ui.min' import { confirmSingleOption } from '#/components/helpers/confirmComponent/ConfirmComponent.vue' import { getToken } from '#/pages/simulatorHandler.vue' import { ProjectData } from './types/setup.types' -import { BackgroundArea } from './interface/backgroundArea' -declare var DPR: number -declare var width: number -declare var height: number -declare var embed: boolean -declare var lightMode: boolean interface PlotArea { setup: () => void } -const typedBackgroundArea = backgroundArea as unknown as BackgroundArea -const typedPlotArea = plotArea as unknown as PlotArea - /** * to resize window and setup things it * sets up new width for the canvas variables. @@ -47,17 +38,26 @@ const typedPlotArea = plotArea as unknown as PlotArea * @category setup */ export function resetup(): void { - DPR = window.devicePixelRatio || 1 - if (lightMode) { - DPR = 1 + window.DPR = window.devicePixelRatio || 1 + if (window.lightMode) { + window.DPR = 1 } - width = document.getElementById('simulationArea')!.clientWidth * DPR - if (!embed) { + const simulationAreaElement = document.getElementById('simulationArea') + if (!simulationAreaElement) { + throw new Error('simulationArea element not found') + } + window.width = simulationAreaElement.clientWidth * window.DPR + if (!window.embed) { const toolbar = document.getElementById('toolbar') - height = - (document.body.clientHeight - (toolbar?.clientHeight || 0)) * DPR + window.height = + (document.body.clientHeight - (toolbar?.clientHeight || 0)) * + window.DPR } else { - height = document.getElementById('simulation')!.clientHeight * DPR + const simulationElement = document.getElementById('simulation') + if (!simulationElement) { + throw new Error('simulation element not found') + } + window.height = simulationElement.clientHeight * window.DPR } // setup simulationArea and backgroundArea variables used to make changes to canvas. backgroundArea.setup() @@ -68,24 +68,24 @@ export function resetup(): void { const canvasArea = document.getElementById('canvasArea') if (bgArea) { - bgArea.style.height = height / DPR + 100 + 'px' - bgArea.style.width = width / DPR + 100 + 'px' + bgArea.style.height = window.height / window.DPR + 100 + 'px' + bgArea.style.width = window.width / window.DPR + 100 + 'px' } if (canvasArea) { - canvasArea.style.height = height / DPR + 'px' + canvasArea.style.height = window.height / window.DPR + 'px' } - simulationArea.canvas.width = width - simulationArea.canvas.height = height + simulationArea.canvas.width = window.width + simulationArea.canvas.height = window.height - if (typedBackgroundArea.canvas) { - typedBackgroundArea.canvas.width = width + 100 * DPR - typedBackgroundArea.canvas.height = height + 100 * DPR + if (backgroundArea.canvas) { + backgroundArea.canvas.width = window.width + 100 * window.DPR + backgroundArea.canvas.height = window.height + 100 * window.DPR } - if (!embed) { - typedPlotArea.setup() + if (!window.embed) { + ;(plotArea as PlotArea).setup() } updateCanvasSet(true) update() // INEFFICIENT, needs to be deprecated @@ -134,6 +134,14 @@ async function fetchProjectData(projectId: number): Promise { ) if (response.ok) { const data: ProjectData = await response.json() + const simulatorVersion = data.simulatorVersion + const projectName = data.name + if(!simulatorVersion){ + window.location.href = `/simulator/edit/${projectName}` + } + if(simulatorVersion && simulatorVersion != "v0"){ + window.location.href = `/simulatorvue/edit/${projectName}?simver=${simulatorVersion}` + } await load(data as any) await simulationArea.changeClockTime(data.timePeriod || 500) $('.loadingIcon').fadeOut() From e8decbe79da8bf9bfbca319624b48136b5238766 Mon Sep 17 00:00:00 2001 From: ShinichiShi Date: Tue, 21 Oct 2025 01:19:18 +0530 Subject: [PATCH 3/3] apply coderabbit suggestion --- src/simulator/src/setup.ts | 65 ++++++++++++++++++-------- src/simulator/src/types/setup.types.ts | 24 +++++----- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/simulator/src/setup.ts b/src/simulator/src/setup.ts index 4ea4e5811..8f5c008ba 100644 --- a/src/simulator/src/setup.ts +++ b/src/simulator/src/setup.ts @@ -100,10 +100,11 @@ window.onorientationchange = resetup // listener window.addEventListener('orientationchange', resetup) // listener /** - * function to setup environment variables like projectId and DPR + * Function to setup environment variables like projectId and DPR * @category setup + * @export */ -function setupEnvironment(): void { +export function setupEnvironment(): void { setupModules() const projectId = generateId() window.projectId = projectId @@ -120,7 +121,7 @@ function setupEnvironment(): void { * @param {number} projectId The ID of the project to fetch data for * @category setup */ -async function fetchProjectData(projectId: number): Promise { +export async function fetchProjectData(projectId: number): Promise { try { const response = await fetch( `/api/v1/projects/${projectId}/circuit_data`, @@ -134,14 +135,24 @@ async function fetchProjectData(projectId: number): Promise { ) if (response.ok) { const data: ProjectData = await response.json() - const simulatorVersion = data.simulatorVersion + const simulatorVersion = data.simulatorVersion const projectName = data.name - if(!simulatorVersion){ - window.location.href = `/simulator/edit/${projectName}` - } - if(simulatorVersion && simulatorVersion != "v0"){ - window.location.href = `/simulatorvue/edit/${projectName}?simver=${simulatorVersion}` + const safeName = encodeURIComponent(projectName ?? '') + + if (!simulatorVersion) { + window.location.assign(`/simulator/edit/${safeName}`) + return + } + + if (simulatorVersion !== 'v0') { + window.location.assign( + `/simulatorvue/edit/${safeName}?simver=${encodeURIComponent( + simulatorVersion + )}` + ) + return } + await load(data as any) await simulationArea.changeClockTime(data.timePeriod || 500) $('.loadingIcon').fadeOut() @@ -160,20 +171,33 @@ async function fetchProjectData(projectId: number): Promise { * Improvement to eliminate delay caused by setTimeout in previous implementation revert if issues arise. * @category setup */ -async function loadProjectData(): Promise { +export async function loadProjectData(): Promise { window.logixProjectId = window.logixProjectId ?? 0 if (window.logixProjectId !== 0) { $('.loadingIcon').fadeIn() - await fetchProjectData(window.logixProjectId) + try { + await fetchProjectData(window.logixProjectId) + } catch (error) { + console.error('Failed to load project data:', error) + $('.loadingIcon').fadeOut() + showMessage('Failed to load project. Please try again.') + } } else if (localStorage.getItem('recover_login') && window.isUserLoggedIn) { // Restore unsaved data and save - const item = localStorage.getItem('recover_login') - if (item) { - const data = JSON.parse(item) - await load(data as any) - localStorage.removeItem('recover') - localStorage.removeItem('recover_login') - await save() + try { + const item = localStorage.getItem('recover_login') + if (item) { + const data = JSON.parse(item) as unknown as ProjectData + await load(data as any) + localStorage.removeItem('recover') + localStorage.removeItem('recover_login') + await save() + } + } catch (error) { + console.error('Failed to recover project data:', error) + showMessage( + 'Failed to recover project data. The saved data may be corrupted.' + ) } } else if (localStorage.getItem('recover')) { // Restore unsaved data which didn't get saved due to error @@ -187,9 +211,10 @@ async function loadProjectData(): Promise { * Show tour guide if it hasn't been completed yet. * The tour is shown after a delay of 2 seconds. * @category setup + * @export */ -function showTour(): void { - if (!localStorage.getItem('tutorials_tour_done') && !embed) { +export function showTour(): void { + if (!localStorage.getItem('tutorials_tour_done') && !window.embed) { setTimeout(() => { showTourGuide() }, 2000) diff --git a/src/simulator/src/types/setup.types.ts b/src/simulator/src/types/setup.types.ts index ebdc88b63..90ad8a2a3 100644 --- a/src/simulator/src/types/setup.types.ts +++ b/src/simulator/src/types/setup.types.ts @@ -1,18 +1,20 @@ declare global { interface Window { - projectId: string; - data: Record; - logixProjectId: number; - isUserLoggedIn: boolean; - DPR: number; - width: number; - height: number; - embed: boolean; - lightMode: boolean; + projectId: string + data: Record + logixProjectId: number + isUserLoggedIn: boolean + DPR: number + width: number + height: number + embed: boolean + lightMode: boolean } } export interface ProjectData { - timePeriod?: number; - [key: string]: any; + timePeriod?: number + simulatorVersion?: string + name?: string + [key: string]: any }