Skip to content

Commit 09ad57d

Browse files
committed
fix: correct dom-to-image import syntax in save.ts
- Changed from incorrect named import {domtoimage} to default import - Fixed missing space in import statement - Verified all dependencies are installed and available
1 parent 118d8b3 commit 09ad57d

File tree

1 file changed

+108
-71
lines changed

1 file changed

+108
-71
lines changed

src/simulator/src/data/save.js renamed to src/simulator/src/data/save.ts

Lines changed: 108 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,37 @@ import { layoutModeGet, toggleLayoutMode } from '../layoutMode'
1212
import { verilogModeGet } from '../Verilog2CV'
1313
import domtoimage from 'dom-to-image'
1414
import canvasToSvg from "canvas-to-svg"
15-
import { useProjectStore } from '#/store/projectStore'
16-
import { provideProjectName } from '#/components/helpers/promptComponent/PromptComponent.vue'
17-
import { UpdateProjectDetail } from '#/components/helpers/createNewProject/UpdateProjectDetail.vue'
18-
import { confirmOption } from '#/components/helpers/confirmComponent/ConfirmComponent.vue'
19-
import { getToken } from '#/pages/simulatorHandler.vue'
15+
import { useProjectStore } from '../../../store/projectStore'
16+
import { provideProjectName } from '../../../components/helpers/promptComponent/PromptComponent.vue'
17+
import { UpdateProjectDetail } from '../../../components/helpers/createNewProject/UpdateProjectDetail.vue'
18+
import { confirmOption } from '../../../components/helpers/confirmComponent/ConfirmComponent.vue'
19+
import { getToken } from '../../../pages/simulatorHandler.vue'
2020
import { renderOrder } from '../metadata'
2121

22-
// var projectName = undefined
22+
// Extend Window interface to include global variables
23+
declare global {
24+
interface Window {
25+
globalScope: any
26+
width: number
27+
height: number
28+
projectId: string | number | undefined
29+
isUserLoggedIn: boolean
30+
logixProjectId: string | number | undefined
31+
}
32+
}
33+
34+
// Get global variables from window
35+
const globalScope = window.globalScope
36+
let width = window.width
37+
let height = window.height
38+
const projectId = window.projectId
2339

2440
/**
2541
* Function to set the name of project.
2642
* @param {string} name - name for project
2743
* @category data
2844
*/
29-
export function setProjectName(name) {
45+
export function setProjectName(name: string | undefined): void {
3046
const projectStore = useProjectStore()
3147
if (name == undefined) {
3248
// $('#projectName').html('Untitled')
@@ -43,19 +59,20 @@ export function setProjectName(name) {
4359
* @param {string} name - name for project
4460
* @category data
4561
*/
46-
export function getProjectName() {
62+
export function getProjectName(): string | undefined {
4763
const projectStore = useProjectStore()
4864
if (projectStore.getProjectNameDefined)
4965
return projectStore.getProjectName.trim()
5066
else return undefined
5167
}
68+
5269
/**
5370
* Helper function to save canvas as image based on image type
5471
* @param {string} name -name of the circuit
5572
* @param {string} imgType - image type ex: png,jpg etc.
5673
* @category data
5774
*/
58-
function downloadAsImg(name, imgType) {
75+
function downloadAsImg(name: string, imgType: string): void {
5976
const gh = simulationArea.canvas.toDataURL(`image/${imgType}`)
6077
const anchor = document.createElement('a')
6178
anchor.href = gh
@@ -66,31 +83,51 @@ function downloadAsImg(name, imgType) {
6683
/**
6784
* Returns the order of tabs in the project
6885
*/
69-
export function getTabsOrder() {
70-
var tabs = document.getElementById('tabsBar').firstChild.children
71-
var order = []
72-
for (let i = 0; i < tabs?.length; i++) {
73-
order.push(tabs[i].id)
86+
export function getTabsOrder(): string[] {
87+
const tabs = (document.getElementById('tabsBar')?.firstChild as HTMLElement)?.children
88+
const order: string[] = []
89+
for (let i = 0; i < (tabs?.length || 0); i++) {
90+
order.push((tabs as HTMLCollection)[i].id)
7491
}
7592
return order
7693
}
7794

95+
interface SaveData {
96+
name: string
97+
timePeriod: number
98+
clockEnabled: boolean
99+
projectId: string | number | undefined
100+
focussedCircuit: string | number
101+
orderedTabs: string[]
102+
scopes: any[]
103+
}
104+
78105
/**
79106
* Generates JSON of the entire project
80107
* @param {string} name - the name of project
81108
* @return {JSON}
82109
* @category data
83110
*/
84-
export async function generateSaveData(name, setName = true) {
85-
let data = {}
111+
export async function generateSaveData(name?: string, setName: boolean = true): Promise<string | Error> {
112+
let data: SaveData = {
113+
name: '',
114+
timePeriod: 0,
115+
clockEnabled: false,
116+
projectId: undefined,
117+
focussedCircuit: '',
118+
orderedTabs: [],
119+
scopes: []
120+
}
86121

87122
// Prompts for name, defaults to Untitled
88-
name = getProjectName() || name || (await provideProjectName())
89-
if (name instanceof Error) {
123+
const projectName = getProjectName() || name || (await provideProjectName())
124+
if (projectName instanceof Error) {
90125
return new Error('cancel')
91126
// throw 'save has been canceled'
92-
} else if (name == '') {
127+
} else if (projectName == '') {
93128
name = 'Untitled'
129+
} else {
130+
name = projectName
94131
}
95132
data.name = stripTags(name)
96133
if (setName) setProjectName(data.name)
@@ -104,16 +141,16 @@ export async function generateSaveData(name, setName = true) {
104141

105142
// Project Circuits, each scope is one circuit
106143
data.scopes = []
107-
const dependencyList = {}
108-
const completed = {}
144+
const dependencyList: { [key: string]: string[] } = {}
145+
const completed: { [key: string]: boolean } = {}
109146
// Getting list of dependencies for each circuit
110-
for (id in scopeList) {
147+
for (const id in scopeList) {
111148
dependencyList[id] = scopeList[id].getDependencies()
112149
}
113150

114151
// Helper function to save Scope
115152
// Recursively saves inner subcircuits first, before saving parent circuits
116-
function saveScope(id) {
153+
function saveScope(id: string): void {
117154
if (completed[id]) return
118155

119156
for (let i = 0; i < dependencyList[id].length; i++) {
@@ -139,21 +176,21 @@ export async function generateSaveData(name, setName = true) {
139176
}
140177

141178
// convert to text
142-
data = JSON.stringify(data)
143-
return data
179+
const dataString = JSON.stringify(data)
180+
return dataString
144181
}
145182

146183
// Helper function to download text
147-
function download(filename, text) {
148-
var pom = document.createElement('a')
184+
function download(filename: string, text: string): void {
185+
const pom = document.createElement('a')
149186
pom.setAttribute(
150187
'href',
151188
'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
152189
)
153190
pom.setAttribute('download', filename)
154191

155192
if (document.createEvent) {
156-
var event = document.createEvent('MouseEvents')
193+
const event = document.createEvent('MouseEvents')
157194
event.initEvent('click', true, true)
158195
pom.dispatchEvent(event)
159196
} else {
@@ -171,12 +208,12 @@ function download(filename, text) {
171208
* @category data
172209
*/
173210
export function generateImage(
174-
imgType,
175-
view,
176-
transparent,
177-
resolution,
178-
down = true
179-
) {
211+
imgType: string,
212+
view: string,
213+
transparent: boolean,
214+
resolution: number,
215+
down: boolean = true
216+
): string | undefined {
180217
// Backup all data
181218
const backUpOx = globalScope.ox
182219
const backUpOy = globalScope.oy
@@ -204,7 +241,7 @@ export function generateImage(
204241
const scope = globalScope
205242

206243
// Focus circuit
207-
var flag = 1
244+
const flag = 1
208245
if (flag) {
209246
if (view === 'full') {
210247
findDimensions()
@@ -230,18 +267,18 @@ export function generateImage(
230267

231268
simulationArea.canvas.width = width
232269
simulationArea.canvas.height = height
233-
backgroundArea.canvas.width = width
234-
backgroundArea.canvas.height = height
270+
backgroundArea.canvas!.width = width
271+
backgroundArea.canvas!.height = height
235272

236273
backgroundArea.context = simulationArea.context
237274

238275
simulationArea.clear()
239276

240277
// Background
241278
if (!transparent) {
242-
simulationArea.context.fillStyle = colors['canvas_fill']
243-
simulationArea.context.rect(0, 0, width, height)
244-
simulationArea.context.fill()
279+
simulationArea.context!.fillStyle = colors['canvas_fill']
280+
simulationArea.context!.rect(0, 0, width, height)
281+
simulationArea.context!.fill()
245282
}
246283

247284
// Draw circuits
@@ -251,11 +288,11 @@ export function generateImage(
251288
}
252289
}
253290

254-
let returnData
291+
let returnData: string | undefined
255292
// If circuit is to be downloaded, download, other wise return dataURL
256293
if (down) {
257294
if (imgType === 'svg') {
258-
const mySerializedSVG = simulationArea.context.getSerializedSvg() // true here, if you need to convert named to numbered entities.
295+
const mySerializedSVG = (simulationArea.context as any).getSerializedSvg() // true here, if you need to convert named to numbered entities.
259296
download(`${globalScope.name}.svg`, mySerializedSVG)
260297
} else {
261298
downloadAsImg(globalScope.name, imgType)
@@ -269,8 +306,8 @@ export function generateImage(
269306
height = backUpHeight
270307
simulationArea.canvas.width = width
271308
simulationArea.canvas.height = height
272-
backgroundArea.canvas.width = width
273-
backgroundArea.canvas.height = height
309+
backgroundArea.canvas!.width = width
310+
backgroundArea.canvas!.height = height
274311
globalScope.scale = backUpScale
275312
backgroundArea.context = backUpContextBackground
276313
simulationArea.context = backUpContextSimulation
@@ -282,22 +319,21 @@ export function generateImage(
282319
if (!down) return returnData
283320
}
284321

285-
async function crop(dataURL, w, h) {
322+
async function crop(dataURL: string, w: number, h: number): Promise<string> {
286323
//get empty second canvas
287-
var myCanvas = document.createElement('CANVAS')
324+
const myCanvas = document.createElement('CANVAS') as HTMLCanvasElement
288325
myCanvas.width = w
289326
myCanvas.height = h
290-
var myContext = myCanvas.getContext('2d')
291-
var myImage
292-
var img = new Image()
327+
const myContext = myCanvas.getContext('2d')
328+
const img = new Image()
293329
return new Promise(function (resolved, rejected) {
294330
img.src = dataURL
295331
img.onload = () => {
296-
myContext.drawImage(img, 0, 0, w, h, 0, 0, w, h)
297-
myContext.save()
332+
myContext?.drawImage(img, 0, 0, w, h, 0, 0, w, h)
333+
myContext?.save()
298334

299335
//create a new data URL
300-
myImage = myCanvas.toDataURL('image/jpeg')
336+
const myImage = myCanvas.toDataURL('image/jpeg')
301337
resolved(myImage)
302338
}
303339
})
@@ -308,22 +344,22 @@ async function crop(dataURL, w, h) {
308344
* @return {JSON}
309345
* @category data
310346
*/
311-
async function generateImageForOnline() {
347+
async function generateImageForOnline(): Promise<string> {
312348
// Verilog Mode -> Different logic
313349
// Fix aspect ratio to 1.6
314350
// Ensure image is approximately 700 x 440
315-
var ratio = 1.6
351+
const ratio = 1.6
316352
if (verilogModeGet()) {
317-
var node = document.getElementsByClassName('CodeMirror')[0]
353+
const node = document.getElementsByClassName('CodeMirror')[0] as HTMLElement
318354
// var node = document.getElementsByClassName('CodeMirror')[0];
319-
var prevHeight = window.getComputedStyle(node).height
320-
var prevWidth = window.getComputedStyle(node).width
321-
var baseWidth = 500
322-
var baseHeight = Math.round(baseWidth / ratio)
355+
const prevHeight = window.getComputedStyle(node).height
356+
const prevWidth = window.getComputedStyle(node).width
357+
const baseWidth = 500
358+
const baseHeight = Math.round(baseWidth / ratio)
323359
node.style.height = baseHeight + 'px'
324360
node.style.width = baseWidth + 'px'
325361

326-
var data = await domtoimage.toJpeg(node)
362+
let data = await domtoimage.toJpeg(node)
327363
node.style.width = prevWidth
328364
node.style.height = prevHeight
329365
data = await crop(data, baseWidth, baseHeight)
@@ -348,34 +384,35 @@ async function generateImageForOnline() {
348384
440 / (simulationArea.maxHeight - simulationArea.minHeight)
349385
)
350386

351-
data = generateImage('jpeg', 'current', false, resolution, false)
387+
const data = generateImage('jpeg', 'current', false, resolution, false)
352388

353389
// Restores Focus
354390
globalScope.centerFocus(false)
355-
return data
391+
return data as string
356392
}
393+
357394
/**
358395
* Function called when you save acircuit online
359396
* @category data
360397
* @exports save
361398
*/
362-
export default async function save() {
399+
export default async function save(): Promise<void> {
363400
if (layoutModeGet()) toggleLayoutMode()
364401

365402
projectSavedSet(true)
366403

367404
const data = await generateSaveData()
368405
if (data instanceof Error) return
369-
let loadingIcon = document.querySelector('.loadingIcon');
406+
let loadingIcon = document.querySelector('.loadingIcon') as HTMLElement;
370407
loadingIcon.style.transition = 'opacity 0.5s linear';
371408
loadingIcon.style.opacity = '1';
372409

373410
const projectName = getProjectName()
374-
var imageData = await generateImageForOnline()
411+
const imageData = await generateImageForOnline()
375412

376-
const headers = {
413+
const headers: HeadersInit = {
377414
'Content-Type': 'application/json',
378-
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'),
415+
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
379416
Authorization: `Token ${getToken('cvt')}`,
380417
}
381418

@@ -390,12 +427,12 @@ export default async function save() {
390427
)
391428
window.location.href = '/users/sign_in'
392429
else {
393-
let loadingIcon = document.querySelector('.loadingIcon')
430+
let loadingIcon = document.querySelector('.loadingIcon') as HTMLElement
394431
loadingIcon.style.transition = 'opacity 0.2s';
395432
loadingIcon.style.opacity = '0';
396433
}
397434
// eslint-disable-next-line camelcase
398-
} else if ([0, undefined, null, '', '0'].includes(window.logixProjectId)) {
435+
} else if ([0, undefined, null, '', '0'].includes(window.logixProjectId as any)) {
399436
// Create new project - this part needs to be improved and optimised
400437
// const form = $('<form/>', {
401438
// action: '/api/v1/simulator/create',
@@ -447,7 +484,7 @@ export default async function save() {
447484
`We have Created a new project: ${projectName} in our servers.`
448485
)
449486

450-
let loadingIcon = document.querySelector('.loadingIcon')
487+
let loadingIcon = document.querySelector('.loadingIcon') as HTMLElement
451488
loadingIcon.style.transition = 'opacity 0.2s';
452489
loadingIcon.style.opacity = '0';
453490

@@ -520,7 +557,7 @@ export default async function save() {
520557
"There was an error, we couldn't save to our servers"
521558
)
522559
}
523-
let loadingIcon = document.querySelector('.loadingIcon')
560+
let loadingIcon = document.querySelector('.loadingIcon') as HTMLElement
524561
loadingIcon.style.transition = 'opacity 0.2s';
525562
loadingIcon.style.opacity = '0';
526563
})

0 commit comments

Comments
 (0)