@testgorilla/tgo-coding-test 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +49 -2
  2. package/esm2022/index.mjs +12 -0
  3. package/esm2022/lib/components/code-editor/code-editor.component.mjs +335 -0
  4. package/esm2022/lib/components/code-editor/code-editor.service.mjs +72 -0
  5. package/esm2022/lib/components/code-editor/helpers/c-helper.mjs +40 -0
  6. package/esm2022/lib/components/code-editor/helpers/code-editor-helper.base.mjs +11 -0
  7. package/esm2022/lib/components/code-editor/helpers/code-editor-helper.model.mjs +2 -0
  8. package/esm2022/lib/components/code-editor/helpers/cpp-helper.mjs +41 -0
  9. package/esm2022/lib/components/code-editor/helpers/csharp-helper.mjs +42 -0
  10. package/esm2022/lib/components/code-editor/helpers/go-helper.mjs +42 -0
  11. package/esm2022/lib/components/code-editor/helpers/index.mjs +16 -0
  12. package/esm2022/lib/components/code-editor/helpers/java-helper.mjs +42 -0
  13. package/esm2022/lib/components/code-editor/helpers/javascript-helper.mjs +26 -0
  14. package/esm2022/lib/components/code-editor/helpers/kotlin-helper.mjs +42 -0
  15. package/esm2022/lib/components/code-editor/helpers/php-helper.mjs +26 -0
  16. package/esm2022/lib/components/code-editor/helpers/python-helper.mjs +26 -0
  17. package/esm2022/lib/components/code-editor/helpers/r-helper.mjs +26 -0
  18. package/esm2022/lib/components/code-editor/helpers/ruby-helper.mjs +26 -0
  19. package/esm2022/lib/components/code-editor/helpers/scala-helper.mjs +41 -0
  20. package/esm2022/lib/components/code-editor/helpers/sql-helper.mjs +34 -0
  21. package/esm2022/lib/components/code-editor/helpers/swift-helper.mjs +40 -0
  22. package/esm2022/lib/components/code-editor/helpers/typescript-helper.mjs +41 -0
  23. package/esm2022/lib/components/code-editor/models/code-editor.model.mjs +2 -0
  24. package/esm2022/lib/components/code-editor/models/coding-snapshot.model.mjs +2 -0
  25. package/esm2022/lib/components/coding-question/coding-question.component.mjs +126 -0
  26. package/esm2022/lib/components/coding-section/coding-section.component.mjs +188 -0
  27. package/esm2022/lib/components/common/truncated-text/truncated-text.component.mjs +38 -0
  28. package/esm2022/lib/components/configurations/configurations.component.mjs +97 -0
  29. package/esm2022/lib/components/instructions/instructions.component.mjs +139 -0
  30. package/esm2022/lib/components/panel/panel.component.mjs +34 -0
  31. package/esm2022/lib/components/runnable-editor/runnable-editor.component.mjs +169 -0
  32. package/esm2022/lib/components/tests/test-cases/test-cases.component.mjs +198 -0
  33. package/esm2022/lib/components/tests/test-cases-content/test-cases-content.component.mjs +96 -0
  34. package/esm2022/lib/components/tests/test-cases-status/test-cases-status.component.mjs +21 -0
  35. package/esm2022/lib/components/tests/test-results.component.mjs +127 -0
  36. package/esm2022/lib/components/tgo-coding-test/tgo-coding-test.component.mjs +280 -0
  37. package/esm2022/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.mjs +476 -0
  38. package/esm2022/lib/config/index.mjs +2 -0
  39. package/esm2022/lib/config/tgo-coding-test.config.mjs +2 -0
  40. package/esm2022/lib/config/tgo-coding-test.provider.mjs +34 -0
  41. package/esm2022/lib/config/tgo-coding-test.token.mjs +14 -0
  42. package/esm2022/lib/models/auto-saved-data.mjs +2 -0
  43. package/esm2022/lib/models/code-event.mjs +2 -0
  44. package/esm2022/lib/models/coderunner-execution-results.mjs +2 -0
  45. package/esm2022/lib/models/configs.mjs +2 -0
  46. package/esm2022/lib/models/language-change-action.mjs +2 -0
  47. package/esm2022/lib/models/lat-languages.mjs +3 -0
  48. package/esm2022/lib/models/mixpanel-events.mjs +2 -0
  49. package/esm2022/lib/models/mode.mjs +2 -0
  50. package/esm2022/lib/models/paste-data.mjs +2 -0
  51. package/esm2022/lib/models/programming-language.mjs +2 -0
  52. package/esm2022/lib/models/test-cases.mjs +7 -0
  53. package/esm2022/lib/models/theme.mjs +2 -0
  54. package/esm2022/lib/models/translations.mjs +2 -0
  55. package/esm2022/lib/models/view-mode.mjs +8 -0
  56. package/esm2022/lib/pipes/memoize-func.pipe.mjs +39 -0
  57. package/esm2022/lib/services/candidate-coding-test-services/candidature-api.service.mjs +19 -0
  58. package/esm2022/lib/services/candidate-coding-test-services/coderunner-api.service.mjs +58 -0
  59. package/esm2022/lib/services/candidate-coding-test-services/coding-test-tour.service.mjs +89 -0
  60. package/esm2022/lib/services/candidate-coding-test-services/coding-test.service.mjs +490 -0
  61. package/esm2022/lib/services/candidate-coding-test-services/index.mjs +5 -0
  62. package/esm2022/lib/services/coding-test-config.service.mjs +51 -0
  63. package/esm2022/lib/services/configurations.service.mjs +89 -0
  64. package/esm2022/lib/services/lib-coding-test.service.mjs +106 -0
  65. package/esm2022/lib/services/storage.service.mjs +624 -0
  66. package/esm2022/lib/services/test-cases.service.mjs +30 -0
  67. package/esm2022/lib/services/theme.service.mjs +36 -0
  68. package/esm2022/lib/utils/additional-languages/erlang.mjs +103 -0
  69. package/esm2022/lib/utils/resize-element.mjs +13 -0
  70. package/esm2022/lib/utils/time-to-ms.util.mjs +11 -0
  71. package/esm2022/shared/index.mjs +5 -0
  72. package/esm2022/shared/lib/components/audio-animation/audio-animation.component.mjs +114 -0
  73. package/esm2022/shared/lib/components/audio-animation/index.mjs +2 -0
  74. package/esm2022/shared/lib/components/index.mjs +3 -0
  75. package/esm2022/shared/lib/components/vimeo-video/index.mjs +2 -0
  76. package/esm2022/shared/lib/components/vimeo-video/vimeo-video.component.mjs +101 -0
  77. package/esm2022/shared/lib/models/answer.mjs +2 -0
  78. package/esm2022/shared/lib/models/assessment.mjs +2 -0
  79. package/esm2022/shared/lib/models/environment.mjs +2 -0
  80. package/esm2022/shared/lib/models/index.mjs +9 -0
  81. package/esm2022/shared/lib/models/question-component.mjs +2 -0
  82. package/esm2022/shared/lib/models/question.mjs +2 -0
  83. package/esm2022/shared/lib/models/test.mjs +2 -0
  84. package/esm2022/shared/lib/models/translations.mjs +2 -0
  85. package/esm2022/shared/lib/models/window.mjs +2 -0
  86. package/esm2022/shared/lib/services/api/api.service.mjs +97 -0
  87. package/esm2022/shared/lib/services/api/mocked-api.service.mjs +131 -0
  88. package/esm2022/shared/lib/services/environment/environment.service.mjs +13 -0
  89. package/esm2022/shared/lib/services/index.mjs +10 -0
  90. package/esm2022/shared/lib/services/localization/languages.model.mjs +19 -0
  91. package/esm2022/shared/lib/services/localization/transloco-lazy-module-utils.mjs +27 -0
  92. package/esm2022/shared/lib/services/localization/transloco-testing.module.mjs +11 -0
  93. package/esm2022/shared/lib/services/media/media.service.mjs +129 -0
  94. package/esm2022/shared/lib/services/mixpanel/mixpanel.service.mjs +30 -0
  95. package/esm2022/shared/lib/services/theme/theme.service.mjs +24 -0
  96. package/esm2022/shared/test-mocks/assessment-test.mock.mjs +112 -0
  97. package/esm2022/shared/test-mocks/index.mjs +3 -0
  98. package/esm2022/shared/test-mocks/tgo-ui.mock.mjs +39 -0
  99. package/esm2022/testgorilla-tgo-coding-test.mjs +5 -0
  100. package/fesm2022/testgorilla-tgo-coding-test.mjs +4526 -0
  101. package/fesm2022/testgorilla-tgo-coding-test.mjs.map +1 -0
  102. package/{src/index.ts → index.d.ts} +2 -19
  103. package/lib/components/code-editor/code-editor.component.d.ts +54 -0
  104. package/lib/components/code-editor/code-editor.service.d.ts +12 -0
  105. package/lib/components/code-editor/helpers/c-helper.d.ts +11 -0
  106. package/lib/components/code-editor/helpers/code-editor-helper.base.d.ts +8 -0
  107. package/lib/components/code-editor/helpers/code-editor-helper.model.d.ts +62 -0
  108. package/lib/components/code-editor/helpers/cpp-helper.d.ts +11 -0
  109. package/lib/components/code-editor/helpers/csharp-helper.d.ts +12 -0
  110. package/lib/components/code-editor/helpers/go-helper.d.ts +12 -0
  111. package/lib/components/code-editor/helpers/java-helper.d.ts +12 -0
  112. package/lib/components/code-editor/helpers/javascript-helper.d.ts +10 -0
  113. package/lib/components/code-editor/helpers/kotlin-helper.d.ts +12 -0
  114. package/lib/components/code-editor/helpers/php-helper.d.ts +10 -0
  115. package/lib/components/code-editor/helpers/python-helper.d.ts +10 -0
  116. package/lib/components/code-editor/helpers/r-helper.d.ts +10 -0
  117. package/lib/components/code-editor/helpers/ruby-helper.d.ts +10 -0
  118. package/lib/components/code-editor/helpers/scala-helper.d.ts +12 -0
  119. package/lib/components/code-editor/helpers/sql-helper.d.ts +10 -0
  120. package/lib/components/code-editor/helpers/swift-helper.d.ts +11 -0
  121. package/lib/components/code-editor/helpers/typescript-helper.d.ts +11 -0
  122. package/lib/components/code-editor/models/code-editor.model.d.ts +8 -0
  123. package/lib/components/code-editor/models/coding-snapshot.model.d.ts +4 -0
  124. package/lib/components/coding-question/coding-question.component.d.ts +45 -0
  125. package/lib/components/coding-section/coding-section.component.d.ts +52 -0
  126. package/lib/components/common/truncated-text/truncated-text.component.d.ts +13 -0
  127. package/lib/components/configurations/configurations.component.d.ts +40 -0
  128. package/lib/components/instructions/instructions.component.d.ts +48 -0
  129. package/lib/components/panel/panel.component.d.ts +12 -0
  130. package/lib/components/runnable-editor/runnable-editor.component.d.ts +53 -0
  131. package/lib/components/tests/test-cases/test-cases.component.d.ts +46 -0
  132. package/lib/components/tests/test-cases-content/test-cases-content.component.d.ts +26 -0
  133. package/lib/components/tests/test-cases-status/test-cases-status.component.d.ts +9 -0
  134. package/lib/components/tests/test-results.component.d.ts +33 -0
  135. package/lib/components/tgo-coding-test/tgo-coding-test.component.d.ts +69 -0
  136. package/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.d.ts +101 -0
  137. package/{src/lib/config/index.ts → lib/config/index.d.ts} +0 -1
  138. package/lib/config/tgo-coding-test.config.d.ts +24 -0
  139. package/{src/lib/config/tgo-coding-test.provider.ts → lib/config/tgo-coding-test.provider.d.ts} +6 -18
  140. package/lib/config/tgo-coding-test.token.d.ts +9 -0
  141. package/lib/models/auto-saved-data.d.ts +42 -0
  142. package/lib/models/code-event.d.ts +15 -0
  143. package/lib/models/coderunner-execution-results.d.ts +51 -0
  144. package/lib/models/configs.d.ts +15 -0
  145. package/lib/models/language-change-action.d.ts +4 -0
  146. package/lib/models/lat-languages.d.ts +8 -0
  147. package/lib/models/mixpanel-events.d.ts +3 -0
  148. package/lib/models/mode.d.ts +5 -0
  149. package/lib/models/paste-data.d.ts +4 -0
  150. package/lib/models/programming-language.d.ts +8 -0
  151. package/lib/models/test-cases.d.ts +67 -0
  152. package/lib/models/theme.d.ts +4 -0
  153. package/lib/models/translations.d.ts +1 -0
  154. package/lib/models/view-mode.d.ts +6 -0
  155. package/{src/lib/pipes/memoize-func.pipe.ts → lib/pipes/memoize-func.pipe.d.ts} +6 -14
  156. package/lib/services/candidate-coding-test-services/candidature-api.service.d.ts +10 -0
  157. package/lib/services/candidate-coding-test-services/coderunner-api.service.d.ts +18 -0
  158. package/lib/services/candidate-coding-test-services/coding-test-tour.service.d.ts +22 -0
  159. package/lib/services/candidate-coding-test-services/coding-test.service.d.ts +68 -0
  160. package/{src/lib/services/candidate-coding-test-services/index.ts → lib/services/candidate-coding-test-services/index.d.ts} +1 -1
  161. package/lib/services/coding-test-config.service.d.ts +38 -0
  162. package/lib/services/configurations.service.d.ts +37 -0
  163. package/lib/services/lib-coding-test.service.d.ts +69 -0
  164. package/lib/services/storage.service.d.ts +83 -0
  165. package/lib/services/test-cases.service.d.ts +12 -0
  166. package/lib/services/theme.service.d.ts +17 -0
  167. package/lib/utils/additional-languages/erlang.d.ts +37 -0
  168. package/lib/utils/resize-element.d.ts +2 -0
  169. package/lib/utils/time-to-ms.util.d.ts +1 -0
  170. package/package.json +18 -7
  171. package/shared/index.d.ts +4 -0
  172. package/shared/lib/components/audio-animation/audio-animation.component.d.ts +27 -0
  173. package/shared/lib/components/audio-animation/index.d.ts +1 -0
  174. package/shared/lib/components/index.d.ts +2 -0
  175. package/shared/lib/components/vimeo-video/index.d.ts +1 -0
  176. package/shared/lib/components/vimeo-video/vimeo-video.component.d.ts +24 -0
  177. package/shared/lib/models/answer.d.ts +17 -0
  178. package/shared/lib/models/assessment.d.ts +80 -0
  179. package/shared/lib/models/environment.d.ts +1 -0
  180. package/shared/lib/models/index.d.ts +8 -0
  181. package/shared/lib/models/question-component.d.ts +54 -0
  182. package/shared/lib/models/question.d.ts +102 -0
  183. package/shared/lib/models/test.d.ts +81 -0
  184. package/shared/lib/models/translations.d.ts +1 -0
  185. package/shared/lib/models/window.d.ts +6 -0
  186. package/shared/lib/services/api/api.service.d.ts +25 -0
  187. package/shared/lib/services/api/mocked-api.service.d.ts +35 -0
  188. package/shared/lib/services/environment/environment.service.d.ts +6 -0
  189. package/shared/lib/services/index.d.ts +9 -0
  190. package/shared/lib/services/localization/languages.model.d.ts +15 -0
  191. package/shared/lib/services/localization/transloco-lazy-module-utils.d.ts +11 -0
  192. package/shared/lib/services/localization/transloco-testing.module.d.ts +2 -0
  193. package/shared/lib/services/media/media.service.d.ts +29 -0
  194. package/shared/lib/services/mixpanel/mixpanel.service.d.ts +10 -0
  195. package/shared/lib/services/theme/theme.service.d.ts +8 -0
  196. package/shared/test-mocks/assessment-test.mock.d.ts +21 -0
  197. package/shared/test-mocks/index.d.ts +2 -0
  198. package/shared/test-mocks/tgo-ui.mock.d.ts +21 -0
  199. package/.eslintrc.json +0 -45
  200. package/jest.config.ts +0 -21
  201. package/ng-package.json +0 -14
  202. package/project.json +0 -36
  203. package/src/lib/components/.gitkeep +0 -0
  204. package/src/lib/components/code-editor/code-editor.component.html +0 -10
  205. package/src/lib/components/code-editor/code-editor.component.scss +0 -21
  206. package/src/lib/components/code-editor/code-editor.component.spec.ts +0 -136
  207. package/src/lib/components/code-editor/code-editor.component.ts +0 -369
  208. package/src/lib/components/code-editor/code-editor.mocks.ts +0 -28
  209. package/src/lib/components/code-editor/code-editor.service.spec.ts +0 -160
  210. package/src/lib/components/code-editor/code-editor.service.ts +0 -94
  211. package/src/lib/components/code-editor/helpers/c-helper.spec.ts +0 -39
  212. package/src/lib/components/code-editor/helpers/c-helper.ts +0 -51
  213. package/src/lib/components/code-editor/helpers/code-editor-helper.base.spec.ts +0 -30
  214. package/src/lib/components/code-editor/helpers/code-editor-helper.base.ts +0 -16
  215. package/src/lib/components/code-editor/helpers/code-editor-helper.mocks.ts +0 -24
  216. package/src/lib/components/code-editor/helpers/code-editor-helper.model.ts +0 -67
  217. package/src/lib/components/code-editor/helpers/cpp-helper.spec.ts +0 -40
  218. package/src/lib/components/code-editor/helpers/cpp-helper.ts +0 -52
  219. package/src/lib/components/code-editor/helpers/csharp-helper.spec.ts +0 -42
  220. package/src/lib/components/code-editor/helpers/csharp-helper.ts +0 -55
  221. package/src/lib/components/code-editor/helpers/go-helper.spec.ts +0 -41
  222. package/src/lib/components/code-editor/helpers/go-helper.ts +0 -54
  223. package/src/lib/components/code-editor/helpers/java-helper.spec.ts +0 -41
  224. package/src/lib/components/code-editor/helpers/java-helper.ts +0 -54
  225. package/src/lib/components/code-editor/helpers/javascript-helper.spec.ts +0 -39
  226. package/src/lib/components/code-editor/helpers/javascript-helper.ts +0 -32
  227. package/src/lib/components/code-editor/helpers/kotlin-helper.spec.ts +0 -41
  228. package/src/lib/components/code-editor/helpers/kotlin-helper.ts +0 -54
  229. package/src/lib/components/code-editor/helpers/php-helper.spec.ts +0 -39
  230. package/src/lib/components/code-editor/helpers/php-helper.ts +0 -32
  231. package/src/lib/components/code-editor/helpers/python-helper.spec.ts +0 -39
  232. package/src/lib/components/code-editor/helpers/python-helper.ts +0 -32
  233. package/src/lib/components/code-editor/helpers/r-helper.spec.ts +0 -39
  234. package/src/lib/components/code-editor/helpers/r-helper.ts +0 -32
  235. package/src/lib/components/code-editor/helpers/ruby-helper.spec.ts +0 -39
  236. package/src/lib/components/code-editor/helpers/ruby-helper.ts +0 -32
  237. package/src/lib/components/code-editor/helpers/scala-helper.spec.ts +0 -41
  238. package/src/lib/components/code-editor/helpers/scala-helper.ts +0 -53
  239. package/src/lib/components/code-editor/helpers/sql-helper.spec.ts +0 -87
  240. package/src/lib/components/code-editor/helpers/sql-helper.ts +0 -44
  241. package/src/lib/components/code-editor/helpers/swift-helper.spec.ts +0 -40
  242. package/src/lib/components/code-editor/helpers/swift-helper.ts +0 -51
  243. package/src/lib/components/code-editor/helpers/typescript-helper.spec.ts +0 -40
  244. package/src/lib/components/code-editor/helpers/typescript-helper.ts +0 -52
  245. package/src/lib/components/code-editor/models/code-editor.model.ts +0 -9
  246. package/src/lib/components/code-editor/models/coding-snapshot.model.ts +0 -4
  247. package/src/lib/components/coding-question/coding-question.component.html +0 -78
  248. package/src/lib/components/coding-question/coding-question.component.scss +0 -76
  249. package/src/lib/components/coding-question/coding-question.component.spec.ts +0 -85
  250. package/src/lib/components/coding-question/coding-question.component.ts +0 -102
  251. package/src/lib/components/coding-section/coding-section.component.html +0 -82
  252. package/src/lib/components/coding-section/coding-section.component.scss +0 -64
  253. package/src/lib/components/coding-section/coding-section.component.spec.ts +0 -257
  254. package/src/lib/components/coding-section/coding-section.component.ts +0 -187
  255. package/src/lib/components/coding-test.module.ts +0 -124
  256. package/src/lib/components/common/truncated-text/truncated-text.component.html +0 -6
  257. package/src/lib/components/common/truncated-text/truncated-text.component.scss +0 -18
  258. package/src/lib/components/common/truncated-text/truncated-text.component.spec.ts +0 -84
  259. package/src/lib/components/common/truncated-text/truncated-text.component.ts +0 -37
  260. package/src/lib/components/configurations/configurations.component.html +0 -57
  261. package/src/lib/components/configurations/configurations.component.scss +0 -42
  262. package/src/lib/components/configurations/configurations.component.spec.ts +0 -186
  263. package/src/lib/components/configurations/configurations.component.ts +0 -98
  264. package/src/lib/components/instructions/instructions.component.html +0 -41
  265. package/src/lib/components/instructions/instructions.component.scss +0 -167
  266. package/src/lib/components/instructions/instructions.component.spec.ts +0 -106
  267. package/src/lib/components/instructions/instructions.component.ts +0 -138
  268. package/src/lib/components/panel/panel.component.html +0 -19
  269. package/src/lib/components/panel/panel.component.scss +0 -41
  270. package/src/lib/components/panel/panel.component.spec.ts +0 -40
  271. package/src/lib/components/panel/panel.component.ts +0 -34
  272. package/src/lib/components/runnable-editor/runnable-editor.component.html +0 -75
  273. package/src/lib/components/runnable-editor/runnable-editor.component.scss +0 -55
  274. package/src/lib/components/runnable-editor/runnable-editor.component.spec.ts +0 -124
  275. package/src/lib/components/runnable-editor/runnable-editor.component.ts +0 -155
  276. package/src/lib/components/tests/test-cases/test-cases.component.html +0 -135
  277. package/src/lib/components/tests/test-cases/test-cases.component.scss +0 -220
  278. package/src/lib/components/tests/test-cases/test-cases.component.spec.ts +0 -401
  279. package/src/lib/components/tests/test-cases/test-cases.component.ts +0 -205
  280. package/src/lib/components/tests/test-cases-content/test-cases-content.component.html +0 -94
  281. package/src/lib/components/tests/test-cases-content/test-cases-content.component.scss +0 -103
  282. package/src/lib/components/tests/test-cases-content/test-cases-content.component.spec.ts +0 -122
  283. package/src/lib/components/tests/test-cases-content/test-cases-content.component.ts +0 -102
  284. package/src/lib/components/tests/test-cases-status/test-cases-status.component.html +0 -16
  285. package/src/lib/components/tests/test-cases-status/test-cases-status.component.scss +0 -49
  286. package/src/lib/components/tests/test-cases-status/test-cases-status.component.spec.ts +0 -22
  287. package/src/lib/components/tests/test-cases-status/test-cases-status.component.ts +0 -18
  288. package/src/lib/components/tests/test-results.component.html +0 -119
  289. package/src/lib/components/tests/test-results.component.scss +0 -189
  290. package/src/lib/components/tests/test-results.component.spec.ts +0 -140
  291. package/src/lib/components/tests/test-results.component.ts +0 -98
  292. package/src/lib/components/tgo-coding-test/tgo-coding-test.component.html +0 -96
  293. package/src/lib/components/tgo-coding-test/tgo-coding-test.component.scss +0 -6
  294. package/src/lib/components/tgo-coding-test/tgo-coding-test.component.spec.ts +0 -599
  295. package/src/lib/components/tgo-coding-test/tgo-coding-test.component.ts +0 -279
  296. package/src/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.html +0 -36
  297. package/src/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.scss +0 -183
  298. package/src/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.spec.ts +0 -883
  299. package/src/lib/components/tgo-coding-test-candidate-view/tgo-coding-test-candidate-view.component.ts +0 -575
  300. package/src/lib/config/tgo-coding-test.config.ts +0 -26
  301. package/src/lib/config/tgo-coding-test.token.ts +0 -21
  302. package/src/lib/models/.gitkeep +0 -0
  303. package/src/lib/models/auto-saved-data.ts +0 -51
  304. package/src/lib/models/code-event.ts +0 -17
  305. package/src/lib/models/coderunner-execution-results.ts +0 -58
  306. package/src/lib/models/coding-lib.mocks.ts +0 -246
  307. package/src/lib/models/configs.ts +0 -18
  308. package/src/lib/models/language-change-action.ts +0 -4
  309. package/src/lib/models/lat-languages.ts +0 -12
  310. package/src/lib/models/mixpanel-events.ts +0 -3
  311. package/src/lib/models/mode.ts +0 -5
  312. package/src/lib/models/paste-data.ts +0 -4
  313. package/src/lib/models/programming-language.ts +0 -9
  314. package/src/lib/models/test-cases.ts +0 -74
  315. package/src/lib/models/theme.ts +0 -5
  316. package/src/lib/models/translations.ts +0 -1
  317. package/src/lib/models/view-mode.ts +0 -6
  318. package/src/lib/services/.gitkeep +0 -0
  319. package/src/lib/services/candidate-coding-test-services/candidature-api.service.spec.ts +0 -40
  320. package/src/lib/services/candidate-coding-test-services/candidature-api.service.ts +0 -15
  321. package/src/lib/services/candidate-coding-test-services/coderunner-api.service.spec.ts +0 -134
  322. package/src/lib/services/candidate-coding-test-services/coderunner-api.service.ts +0 -105
  323. package/src/lib/services/candidate-coding-test-services/coding-test-tour.service.spec.ts +0 -161
  324. package/src/lib/services/candidate-coding-test-services/coding-test-tour.service.ts +0 -100
  325. package/src/lib/services/candidate-coding-test-services/coding-test.service.spec.ts +0 -1524
  326. package/src/lib/services/candidate-coding-test-services/coding-test.service.ts +0 -843
  327. package/src/lib/services/coding-test-config.service.ts +0 -48
  328. package/src/lib/services/configurations.service.mocks.ts +0 -77
  329. package/src/lib/services/configurations.service.spec.ts +0 -79
  330. package/src/lib/services/configurations.service.ts +0 -111
  331. package/src/lib/services/index.ts +0 -0
  332. package/src/lib/services/lib-coding-test.service.spec.ts +0 -265
  333. package/src/lib/services/lib-coding-test.service.ts +0 -157
  334. package/src/lib/services/local-storage.service.mocks.ts +0 -22
  335. package/src/lib/services/storage.service.spec.ts +0 -1120
  336. package/src/lib/services/storage.service.ts +0 -729
  337. package/src/lib/services/test-cases.service.spec.ts +0 -53
  338. package/src/lib/services/test-cases.service.ts +0 -29
  339. package/src/lib/services/theme.service.spec.ts +0 -76
  340. package/src/lib/services/theme.service.ts +0 -34
  341. package/src/lib/styles/mixins.scss +0 -86
  342. package/src/lib/styles/styles.scss +0 -112
  343. package/src/lib/styles/variables.scss +0 -105
  344. package/src/lib/utils/.gitkeep +0 -0
  345. package/src/lib/utils/additional-languages/erlang.ts +0 -115
  346. package/src/lib/utils/resize-element.ts +0 -15
  347. package/src/lib/utils/time-to-ms.util.ts +0 -10
  348. package/src/test-setup.ts +0 -1
  349. package/tsconfig.json +0 -16
  350. package/tsconfig.lib.json +0 -12
  351. package/tsconfig.lib.prod.json +0 -9
  352. package/tsconfig.spec.json +0 -13
  353. /package/{src/assets → assets}/i18n/en.json +0 -0
  354. /package/{src/lib/components/code-editor/helpers/index.ts → lib/components/code-editor/helpers/index.d.ts} +0 -0
@@ -1,729 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { LocalStorageService } from 'ngx-webstorage';
3
- import { filter, Subscription } from 'rxjs';
4
- import { CodeEditorLanguages } from '../components/code-editor/helpers/code-editor-helper.model';
5
- import { AutoSavedData, AutoSavedDataV1, AutoSavedDataV2, QuestionData, TestData } from '../models/auto-saved-data';
6
- import { Config } from '../models/configs';
7
- import { AssessmentIdPreview } from '../models/lat-languages';
8
- import { Modes } from '../models/mode';
9
- import { CustomTestCase, ExampleTestCase } from '../models/test-cases';
10
- import { ConfigurationsService } from './configurations.service';
11
- import { LibCodingTestService } from './lib-coding-test.service';
12
- import { timeToMs } from '../utils/time-to-ms.util';
13
-
14
- @Injectable({
15
- providedIn: 'root',
16
- })
17
- export class StorageCodingService {
18
- private readonly CURRENT_STORAGE_VERSION = 2;
19
- private autoSavedData: AutoSavedData = {
20
- version: this.CURRENT_STORAGE_VERSION,
21
- config: {} as Config,
22
- isFullscreen: false,
23
- assessments: {},
24
- lastModified: Date.now(),
25
- };
26
- private readonly key = 'savedData';
27
- private assessmentId: string;
28
- private questionId: string;
29
- private language: CodeEditorLanguages;
30
- private codeSaveEnabled: boolean;
31
- private testCasesSaveEnabled: boolean;
32
- private isLAT: boolean;
33
- private currentMode: Modes;
34
- private isPreview: boolean;
35
- private codeChangeSubscription: Subscription;
36
- private configSubscription: Subscription;
37
- private isFullscreenSubscription: Subscription;
38
- private currentLanguageSubscription: Subscription;
39
- private isCodeComponentAlive = filter(() => !this.configurationsService.getCodeComponentDestroyed());
40
-
41
- // Maximum age of entire storage data in days
42
- private readonly MAX_STORAGE_AGE_DAYS = 7;
43
- // Maximum age for assessment inner data in days
44
- private readonly MAX_QUESTION_DATA_AGE_DAYS = 1;
45
- // Maximum number of assessments to keep
46
- private readonly MAX_ASSESSMENTS = 10;
47
- // The default question ID used for migrated v1 data
48
- private readonly DEFAULT_MIGRATION_QUESTION_ID = 'default-question';
49
-
50
- // todo: remove
51
- // storage = {
52
- // retrieve: (key: string) => {
53
- // return {} as any;
54
- // },
55
- // store: (key: string, value: any) => {
56
- // return {} as any;
57
- // },
58
- // clear: (key: string) => {
59
- // return {} as any;
60
- // },
61
- // };
62
-
63
- constructor(
64
- // todo
65
- private storage: LocalStorageService,
66
- private libCodingTestService: LibCodingTestService,
67
- private configurationsService: ConfigurationsService
68
- ) {
69
- // Perform safety check on localStorage data
70
- this.performStorageSafetyCheck();
71
- }
72
-
73
- /**
74
- * Performs a safety check on localStorage data.
75
- * This is called at service initialization to ensure data integrity.
76
- */
77
- private performStorageSafetyCheck(): void {
78
- try {
79
- const savedData = this.storage.retrieve(this.key);
80
-
81
- // If no data, nothing to check
82
- if (!savedData) {
83
- return;
84
- }
85
-
86
- // Check storage format and migrate if needed
87
- if (!('version' in savedData)) {
88
- // It's v1 format, so we'll migrate it when it's actually needed
89
- // No need to do anything right now
90
- } else {
91
- // It's v2 format, so we can perform cleanup right away
92
- this.autoSavedData = savedData as AutoSavedData;
93
- }
94
- } catch (error) {
95
- // If any error occurs during safety check, reset storage to avoid issues
96
- console.error('Error during storage safety check, resetting storage:', error);
97
- this.autoSavedData = {
98
- version: this.CURRENT_STORAGE_VERSION,
99
- config: {} as Config,
100
- isFullscreen: false,
101
- assessments: {},
102
- lastModified: Date.now(),
103
- };
104
- this.storeData();
105
- }
106
- }
107
-
108
- initializeSaving(): void {
109
- if (!this.codeChangeSubscription) {
110
- this.codeChangeSubscription = this.libCodingTestService.codeChange$
111
- .pipe(this.isCodeComponentAlive)
112
- .subscribe((code: string) => {
113
- if (this.codeSaveEnabled && this.assessmentId && this.questionId) {
114
- this.ensureDataStructure();
115
- const questionData = this.autoSavedData.assessments[this.assessmentId][this.questionId];
116
- const targetTestData = this.isPreview ? questionData.preview : questionData.actual;
117
- targetTestData.code[this.language] = code!;
118
- this.updateLastModified(targetTestData);
119
- this.storeData();
120
- }
121
- });
122
- }
123
-
124
- if (!this.configSubscription) {
125
- this.configSubscription = this.configurationsService.config$
126
- .pipe(this.isCodeComponentAlive)
127
- .subscribe((config: Config) => {
128
- this.autoSavedData.config = { ...config };
129
- this.updateLastModified(this.autoSavedData);
130
- this.storeData();
131
- });
132
- }
133
-
134
- if (!this.isFullscreenSubscription) {
135
- this.isFullscreenSubscription = this.libCodingTestService.isFullscreen$
136
- .pipe(this.isCodeComponentAlive)
137
- .subscribe((isFullscreen: boolean) => {
138
- this.autoSavedData.isFullscreen = isFullscreen;
139
- this.updateLastModified(this.autoSavedData);
140
- this.storeData();
141
- });
142
- }
143
-
144
- if (!this.currentLanguageSubscription && this.isLAT) {
145
- this.currentLanguageSubscription = this.libCodingTestService.currentLanguage$
146
- .pipe(this.isCodeComponentAlive)
147
- .subscribe((language: CodeEditorLanguages) => {
148
- this.autoSavedData.lastLanguageLAT = {
149
- value: language,
150
- version: this.libCodingTestService.getVersion(),
151
- };
152
- this.updateLastModified(this.autoSavedData);
153
- this.storeData();
154
- });
155
- }
156
- }
157
-
158
- setupAutoSavedData(
159
- language: CodeEditorLanguages,
160
- assessmentId: string,
161
- questionId: string,
162
- codeSaveEnabled: boolean,
163
- testCasesSaveEnabled: boolean,
164
- isLAT: boolean,
165
- mode: Modes
166
- ) {
167
- this.language = language;
168
- this.assessmentId = assessmentId;
169
- this.questionId = questionId;
170
- this.codeSaveEnabled = codeSaveEnabled;
171
- this.testCasesSaveEnabled = testCasesSaveEnabled;
172
- this.isLAT = isLAT;
173
- this.currentMode = mode;
174
- this.isPreview = mode === Modes.Preview || mode === Modes.NonAssessmentPreview;
175
-
176
- // Get saved data
177
- const savedData = this.storage.retrieve(this.key);
178
-
179
- // Handle migration if needed
180
- if (savedData) {
181
- // Check if it's v1 schema (no version field)
182
- if (!('version' in savedData)) {
183
- this.migrateFromV1ToV2(savedData as AutoSavedDataV1);
184
- } else {
185
- this.autoSavedData = savedData as AutoSavedData;
186
- }
187
-
188
- // Apply loaded config and fullscreen setting
189
- this.configurationsService.setConfig(this.autoSavedData.config);
190
- this.libCodingTestService.setFullscreen(this.autoSavedData.isFullscreen);
191
- }
192
- }
193
-
194
- private migrateFromV1ToV2(v1Data: AutoSavedDataV1): void {
195
- // Create a new v2 data structure
196
- const v2Data: AutoSavedDataV2 = {
197
- version: this.CURRENT_STORAGE_VERSION,
198
- config: v1Data.config,
199
- isFullscreen: v1Data.isFullscreen,
200
- lastLanguageLAT: v1Data.lastLanguageLAT,
201
- assessments: {},
202
- lastModified: Date.now(),
203
- };
204
-
205
- // Migrate assessment data
206
- // In v1, assessments were directly mapped to TestData
207
- // In v2, we need to organize by questionId
208
- for (const [assessmentId, testData] of Object.entries(v1Data.assessments)) {
209
- if (assessmentId === AssessmentIdPreview) {
210
- continue;
211
- }
212
-
213
- // We use a consistent default questionId for migration to ensure backward compatibility
214
- const defaultQuestionId = this.DEFAULT_MIGRATION_QUESTION_ID;
215
-
216
- // Initialize the assessment entry if it doesn't exist
217
- if (!v2Data.assessments[assessmentId]) {
218
- v2Data.assessments[assessmentId] = {};
219
- }
220
-
221
- // Create question data with the migrated test data
222
- const questionData: QuestionData = {};
223
-
224
- questionData.actual = {
225
- ...testData,
226
- lastModified: Date.now(),
227
- };
228
-
229
- // Set last modified time for the question data
230
- questionData.lastModified = Date.now();
231
-
232
- // Add to the v2 structure
233
- v2Data.assessments[assessmentId][defaultQuestionId] = questionData;
234
- }
235
-
236
- // Update our instance with migrated data
237
- this.autoSavedData = { ...v2Data };
238
-
239
- // Save the migrated data
240
- this.storeData();
241
- }
242
-
243
- private ensureDataStructure(): void {
244
- // Make sure assessment exists
245
- if (!this.autoSavedData.assessments[this.assessmentId]) {
246
- this.autoSavedData.assessments[this.assessmentId] = {};
247
- }
248
-
249
- // Make sure question exists
250
- if (!this.autoSavedData.assessments[this.assessmentId][this.questionId]) {
251
- this.autoSavedData.assessments[this.assessmentId][this.questionId] = {
252
- lastModified: Date.now(),
253
- };
254
- }
255
-
256
- const questionData = this.autoSavedData.assessments[this.assessmentId][this.questionId];
257
-
258
- // Ensure preview or actual exists based on current mode
259
- if (this.isPreview && !questionData.preview) {
260
- questionData.preview = {
261
- code: {},
262
- testCasesLAT: [],
263
- lastModified: Date.now(),
264
- };
265
- } else if (!this.isPreview && !questionData.actual) {
266
- questionData.actual = {
267
- code: {},
268
- testCasesLAT: [],
269
- lastModified: Date.now(),
270
- };
271
- }
272
- }
273
-
274
- private updateLastModified(data: TestData | QuestionData | AutoSavedData): void {
275
- const now = Date.now();
276
- data.lastModified = now;
277
-
278
- // If updating a TestData, also update its parent QuestionData
279
- if ('code' in data && this.assessmentId && this.questionId) {
280
- this.autoSavedData.assessments[this.assessmentId][this.questionId].lastModified = now;
281
- }
282
-
283
- // Always update root timestamp regardless of the object being modified
284
- this.autoSavedData.lastModified = now;
285
- }
286
-
287
- /**
288
- * Cleanup with a temporary age threshold
289
- * @param maxAgeDays Maximum age in days for data to be considered valid
290
- */
291
- private cleanupWithReducedThreshold(maxAgeDays: number): void {
292
- // Call the unified cleanup method with more aggressive parameters
293
- this.cleanupStorageData({
294
- storageAgeMultiplier: 2, // More aggressive multiplier
295
- customStorageAgeDays: maxAgeDays, // Use the provided custom age
296
- minQuestionDataAgeDays: 0.5, // 12 hours minimum
297
- assessmentLimitMultiplier: 0.5, // Half the normal assessment limit
298
- });
299
- }
300
-
301
- /**
302
- * Unified method to clean up localStorage data with configurable intensity
303
- * @param options Cleanup options to control the aggressiveness of the cleanup
304
- */
305
- private cleanupStorageData(options: {
306
- storageAgeMultiplier?: number; // Multiplier for storage age threshold (default: 1)
307
- customStorageAgeDays?: number; // Custom storage age in days (overrides MAX_STORAGE_AGE_DAYS if provided)
308
- useStandardQuestionDataAge?: boolean; // Whether to use standard question data age (default: false)
309
- minQuestionDataAgeDays?: number; // Minimum age for question data in days (default: 0.5 - 12 hours)
310
- assessmentLimitMultiplier?: number; // Multiplier for maximum assessments (default: 1)
311
- }): void {
312
- const now = Date.now();
313
-
314
- // Determine the storage age threshold
315
- const storageAgeDays = options.customStorageAgeDays ?? this.MAX_STORAGE_AGE_DAYS;
316
- const storageAgeThreshold = timeToMs(storageAgeDays); // Convert days to milliseconds
317
- const multiplier = options.storageAgeMultiplier ?? 1;
318
-
319
- // Check if the entire storage is too old and needs cleanup
320
- if (this.autoSavedData.lastModified && now - this.autoSavedData.lastModified > storageAgeThreshold * multiplier) {
321
- // If the entire storage is very old, just reset everything
322
- this.autoSavedData = {
323
- version: this.CURRENT_STORAGE_VERSION,
324
- config: this.autoSavedData.config, // Keep the config settings
325
- isFullscreen: this.autoSavedData.isFullscreen, // Keep fullscreen setting
326
- assessments: {},
327
- lastModified: now,
328
- };
329
- this.storeData();
330
- return;
331
- }
332
-
333
- // Structure for collecting assessment data with metadata
334
- interface AssessmentMetadata {
335
- id: string;
336
- lastModified: number;
337
- }
338
-
339
- const assessmentMetadata: AssessmentMetadata[] = [];
340
-
341
- // Determine the question data age threshold
342
- let questionDataAgeThreshold: number;
343
- if (options.useStandardQuestionDataAge) {
344
- // Use the standard threshold for normal cleanup
345
- questionDataAgeThreshold = timeToMs(this.MAX_QUESTION_DATA_AGE_DAYS);
346
- } else {
347
- // For maintenance/aggressive cleanup, use a custom threshold
348
- const minAgeHours = (options.minQuestionDataAgeDays ?? 0.5) * 24; // Convert days to hours
349
- questionDataAgeThreshold = Math.max(
350
- timeToMs(this.MAX_QUESTION_DATA_AGE_DAYS), // Standard age in milliseconds
351
- timeToMs(minAgeHours, 'hours') // Minimum age in milliseconds
352
- );
353
- }
354
-
355
- // Collect assessments with their latest modification times
356
- for (const [assessmentId, questions] of Object.entries(this.autoSavedData.assessments)) {
357
- let assessmentLastModified = 0;
358
-
359
- // Check all questions in this assessment
360
- let hasValidQuestions = false;
361
-
362
- for (const [questionId, questionData] of Object.entries(questions)) {
363
- // Skip if undefined
364
- if (!questionData) {
365
- continue;
366
- }
367
-
368
- // Get the latest modification time from preview and actual
369
- const previewTime = questionData.preview?.lastModified || 0;
370
- const actualTime = questionData.actual?.lastModified || 0;
371
- const questionLastModified = Math.max(previewTime, actualTime, questionData.lastModified || 0);
372
-
373
- // Check if data is too old - using configured threshold
374
- const isPreviewTooOld = previewTime > 0 && now - previewTime > questionDataAgeThreshold;
375
- const isActualTooOld = actualTime > 0 && now - actualTime > questionDataAgeThreshold;
376
-
377
- // Clean up old data within the question
378
- if (isPreviewTooOld && questionData.preview) {
379
- delete questionData.preview;
380
- }
381
-
382
- if (isActualTooOld && questionData.actual) {
383
- delete questionData.actual;
384
- }
385
-
386
- // If neither preview nor actual exists, remove the question
387
- if (!questionData.preview && !questionData.actual) {
388
- delete questions[questionId];
389
- } else {
390
- hasValidQuestions = true;
391
- assessmentLastModified = Math.max(assessmentLastModified, questionLastModified);
392
- }
393
- }
394
-
395
- // If no valid questions, remove the assessment
396
- if (!hasValidQuestions) {
397
- delete this.autoSavedData.assessments[assessmentId];
398
- } else {
399
- // Add to our list for potential size-based cleanup
400
- assessmentMetadata.push({
401
- id: assessmentId,
402
- lastModified: assessmentLastModified,
403
- });
404
- }
405
- }
406
-
407
- // Determine the assessment limit based on the multiplier
408
- const limitMultiplier = options.assessmentLimitMultiplier ?? 1;
409
- const assessmentLimit = Math.ceil(this.MAX_ASSESSMENTS * limitMultiplier);
410
-
411
- // If we have too many assessments, remove the oldest ones
412
- if (assessmentMetadata.length > assessmentLimit) {
413
- // Sort by lastModified (most recent first)
414
- assessmentMetadata.sort((a, b) => b.lastModified - a.lastModified);
415
-
416
- // Remove oldest assessments that exceed our limit
417
- for (let i = assessmentLimit; i < assessmentMetadata.length; i++) {
418
- delete this.autoSavedData.assessments[assessmentMetadata[i].id];
419
- }
420
- }
421
-
422
- // Save the cleaned data
423
- this.storeData();
424
- }
425
-
426
- changeLanguage(language: CodeEditorLanguages) {
427
- this.language = language;
428
- }
429
-
430
- /**
431
- * Gets data from v1 schema format
432
- * Used for backward compatibility when retrieving data
433
- */
434
- private getDataFromV1Schema(retrievedData: AutoSavedDataV1): string | (ExampleTestCase | CustomTestCase)[] | null | undefined {
435
- // For v1, we need to handle the case where we don't have questionId
436
- // We're now using questionId in the app, but stored data might still be in v1 format
437
-
438
- // For preview data, the assessment ID would be AssessmentIdPreview
439
- if (this.assessmentId === AssessmentIdPreview) {
440
- if (this.isPreview) {
441
- // For preview mode on preview assessment, get the code directly
442
- const code = retrievedData.assessments[this.assessmentId]?.code;
443
- if (code && this.language in code) {
444
- return code[this.language];
445
- }
446
- }
447
- // We don't expect actual/non-preview data for AssessmentIdPreview
448
- return null;
449
- } else {
450
- // For regular assessments, v1 only had code in the "actual" section
451
- if (!this.isPreview) {
452
- const code = retrievedData.assessments[this.assessmentId]?.code;
453
- if (code && this.language in code) {
454
- return code[this.language];
455
- }
456
- }
457
- // We don't have preview data for regular assessments in v1
458
- return null;
459
- }
460
- }
461
-
462
- getSavedCode(): string | null | undefined {
463
- const retrievedData = this.retrieveData();
464
- if (!retrievedData) {
465
- return null;
466
- }
467
-
468
- // Check if using v2 schema
469
- if ('version' in retrievedData) {
470
- // Handle v2 schema
471
- const v2Data = retrievedData;
472
- const assessmentData = v2Data.assessments[this.assessmentId];
473
-
474
- if (!assessmentData) {
475
- return null;
476
- }
477
-
478
- // First try with provided questionId
479
- if (this.questionId && assessmentData[this.questionId]) {
480
- const questionData = assessmentData[this.questionId];
481
- const testData = this.isPreview ? questionData.preview : questionData.actual;
482
- if (testData?.code && this.language in testData.code) {
483
- return testData.code[this.language];
484
- }
485
- }
486
-
487
- if (
488
- this.questionId !== this.DEFAULT_MIGRATION_QUESTION_ID &&
489
- assessmentData[this.DEFAULT_MIGRATION_QUESTION_ID]
490
- ) {
491
- const questionData = assessmentData[this.DEFAULT_MIGRATION_QUESTION_ID];
492
- const testData = this.isPreview ? questionData.preview : questionData.actual;
493
- if (testData?.code && this.language in testData.code) {
494
- return testData.code[this.language];
495
- }
496
- }
497
-
498
- return null;
499
- } else {
500
- // Handle v1 schema for backward compatibility
501
- return this.getDataFromV1Schema(retrievedData) as string;
502
- }
503
- }
504
-
505
- getLastLanguageLAT(): {
506
- value: CodeEditorLanguages;
507
- version: string;
508
- } | null {
509
- const retrievedData = this.retrieveData();
510
- if (!retrievedData) {
511
- return null;
512
- }
513
-
514
- return retrievedData.lastLanguageLAT || null;
515
- }
516
-
517
- getSavedTestCases(): (ExampleTestCase | CustomTestCase)[] | null | undefined {
518
- const retrievedData = this.retrieveData();
519
- if (!retrievedData) {
520
- return null;
521
- }
522
-
523
- // Check if using v2 schema
524
- if ('version' in retrievedData) {
525
- // Handle v2 schema
526
- const v2Data = retrievedData;
527
- const assessmentData = v2Data.assessments[this.assessmentId];
528
-
529
- if (!assessmentData) {
530
- return null;
531
- }
532
-
533
- // First try with provided questionId
534
- if (this.questionId && assessmentData[this.questionId]) {
535
- const questionData = assessmentData[this.questionId];
536
- const testData = this.isPreview ? questionData.preview : questionData.actual;
537
- if (testData?.testCasesLAT) {
538
- return testData.testCasesLAT;
539
- }
540
- }
541
-
542
- // If not found and questionId != DEFAULT_MIGRATION_QUESTION_ID,
543
- // also try with the default migration ID as a fallback
544
- if (
545
- this.questionId !== this.DEFAULT_MIGRATION_QUESTION_ID &&
546
- assessmentData[this.DEFAULT_MIGRATION_QUESTION_ID]
547
- ) {
548
- const questionData = assessmentData[this.DEFAULT_MIGRATION_QUESTION_ID];
549
- const testData = this.isPreview ? questionData.preview : questionData.actual;
550
- if (testData?.testCasesLAT) {
551
- return testData.testCasesLAT;
552
- }
553
- }
554
-
555
- return null;
556
- } else {
557
- // Handle v1 schema test cases (test cases were only in the actual mode)
558
- const v1Data = retrievedData;
559
- if (!this.isPreview && v1Data.assessments[this.assessmentId]?.testCasesLAT) {
560
- return v1Data.assessments[this.assessmentId].testCasesLAT;
561
- }
562
- return null;
563
- }
564
- }
565
-
566
- getSavedConfig(): Config | null {
567
- const retrievedData = this.retrieveData();
568
- return retrievedData?.config ? { ...retrievedData.config } : null;
569
- }
570
-
571
- getSavedFullScreenMode(): boolean | null {
572
- const retrievedData = this.retrieveData();
573
- return retrievedData?.isFullscreen !== undefined ? retrievedData.isFullscreen : null;
574
- }
575
-
576
- clearSavedCode(): void {
577
- this.ensureDataStructure();
578
- const questionData = this.autoSavedData.assessments[this.assessmentId][this.questionId];
579
- const targetTestData = this.isPreview ? [questionData.preview] : [questionData.preview, questionData.actual];
580
-
581
- let hasChanged = false;
582
- targetTestData.forEach(testData => {
583
- if (testData) {
584
- testData.code = {};
585
- this.updateLastModified(testData);
586
- hasChanged = true;
587
- }
588
- });
589
- if (hasChanged) {
590
- this.storeData();
591
- }
592
- }
593
-
594
- clearLastLang(): void {
595
- this.autoSavedData.lastLanguageLAT = null;
596
- this.updateLastModified(this.autoSavedData);
597
- this.storeData();
598
- }
599
-
600
- clearSavedTestCases(): void {
601
- this.ensureDataStructure();
602
- const questionData = this.autoSavedData.assessments[this.assessmentId][this.questionId];
603
- const targetTestData = this.isPreview ? questionData.preview : questionData.actual;
604
-
605
- if (targetTestData) {
606
- const hasNoCode = !Object.keys(targetTestData.code ?? {}).length;
607
-
608
- if (this.isPreview) {
609
- targetTestData.testCasesLAT = [];
610
- this.updateLastModified(targetTestData);
611
- } else if (hasNoCode) {
612
- const allQuestions = this.autoSavedData.assessments[this.assessmentId];
613
- delete allQuestions[this.questionId];
614
- this.autoSavedData.assessments[this.assessmentId] = { ...allQuestions };
615
- this.updateLastModified(this.autoSavedData);
616
- }
617
- this.storeData();
618
- }
619
- }
620
-
621
- updateVersion(version: string): void {
622
- if (this.autoSavedData.lastLanguageLAT) {
623
- this.autoSavedData.lastLanguageLAT.version = version;
624
- this.updateLastModified(this.autoSavedData);
625
- this.storeData();
626
- }
627
- }
628
-
629
- updateTestCases(testCases: (ExampleTestCase | CustomTestCase)[]) {
630
- if (this.assessmentId && this.questionId && this.testCasesSaveEnabled) {
631
- this.ensureDataStructure();
632
- const questionData = this.autoSavedData.assessments[this.assessmentId][this.questionId];
633
- const targetTestData = this.isPreview ? questionData.preview : questionData.actual;
634
-
635
- if (targetTestData) {
636
- targetTestData.testCasesLAT = testCases;
637
- this.updateLastModified(targetTestData);
638
- this.storeData();
639
- }
640
- }
641
- }
642
-
643
- private storeData(): void {
644
- this.storage.store(this.key, this.autoSavedData);
645
- }
646
-
647
- private retrieveData(): AutoSavedData | AutoSavedDataV1 {
648
- return this.storage.retrieve(this.key) as AutoSavedData | AutoSavedDataV1;
649
- }
650
-
651
- /**
652
- * Manually triggers data cleanup and migration.
653
- * Useful for handling large localStorage or migration when needed.
654
- * This can be called from application startup or after major events.
655
- */
656
- performMaintenanceAndCleanup(): void {
657
- // Get current data
658
- const savedData = this.storage.retrieve(this.key);
659
-
660
- // If no data, nothing to do
661
- if (!savedData) {
662
- return;
663
- }
664
-
665
- // Check if migration needed
666
- if (!('version' in savedData)) {
667
- this.migrateFromV1ToV2(savedData as AutoSavedDataV1);
668
- } else {
669
- // Already migrated, just perform cleanup
670
- this.autoSavedData = savedData as AutoSavedData;
671
-
672
- // Perform a more aggressive cleanup for manual maintenance
673
- // by temporarily modifying the cleanup thresholds
674
- const originalMaxAge = this.MAX_STORAGE_AGE_DAYS;
675
- const halfAge = Math.floor(originalMaxAge / 2); // Cut threshold in half
676
-
677
- // Create a custom cleanup function with reduced threshold
678
- this.cleanupWithReducedThreshold(halfAge);
679
- }
680
-
681
- // Verify localStorage size is manageable
682
- try {
683
- const serializedData = JSON.stringify(this.autoSavedData);
684
- const sizeInKB = Math.round(serializedData.length / 1024);
685
-
686
- // If data is too large (over 2MB), perform more aggressive cleanup
687
- if (sizeInKB > 2048) {
688
- console.warn(`Local storage data is large (${sizeInKB}KB), performing deep cleanup`);
689
-
690
- // Use extremely aggressive cleanup settings
691
- this.cleanupStorageData({
692
- storageAgeMultiplier: 0.5, // Even more aggressive - half the normal age
693
- minQuestionDataAgeDays: 0.25, // 6 hours minimum
694
- assessmentLimitMultiplier: 0.2, // Keep only 20% of assessments
695
- });
696
-
697
- // If still too large, keep only a few most recent assessments
698
- const newSerializedData = JSON.stringify(this.autoSavedData);
699
- const newSizeInKB = Math.round(newSerializedData.length / 1024);
700
-
701
- if (newSizeInKB > 1024) {
702
- // Keep only recent assessments
703
- const assessments = this.autoSavedData.assessments;
704
- // Find the newest timestamp in each assessment
705
- const getNewestTimestamp = (obj: Record<string, QuestionData>) =>
706
- Object.values(obj).reduce((max, questionData) => Math.max(max, questionData?.lastModified || 0), 0);
707
- const entries = Object.entries(assessments).sort(
708
- ([, a], [, b]) =>
709
- getNewestTimestamp(b as Record<string, QuestionData>) -
710
- getNewestTimestamp(a as Record<string, QuestionData>)
711
- );
712
-
713
- // Keep only the 5 most recent assessments
714
- const keepCount = Math.min(5, entries.length);
715
- this.autoSavedData.assessments = {};
716
-
717
- for (let i = 0; i < keepCount; i++) {
718
- const [id, data] = entries[i];
719
- this.autoSavedData.assessments[id] = data as Record<string, QuestionData>;
720
- }
721
-
722
- this.storeData();
723
- }
724
- }
725
- } catch (error) {
726
- console.error('Error checking localStorage size', error);
727
- }
728
- }
729
- }